locked
C++/CX: How to call the derived class destructor?

    Question

  • MainPage.Xaml

    <Page x:Class="App1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Grid>
            <Grid x:Name="grid"/>
            <TextBlock x:Name="Msg" FontSize="100" Foreground="White" VerticalAlignment="Top"/>
            <Button Content="Clear" VerticalAlignment="Bottom" Click="Button_Click"/>
        </Grid>
    </Page>

    MainPage.xaml.h

    namespace App1
    {
    	public ref class MainPage sealed
    	{
    	public:
    		MainPage();
    	internal:
    		static property Platform::String^ Text{Platform::String^ get(){ return _Text; } void set(Platform::String^ value){ _Text = value; }};
    	private:
    		static Platform::String^ _Text;
    		void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
    	};
    }

    MainPage.xaml.cpp

    MainPage::MainPage()
    {
    	InitializeComponent();
    	grid->Children->Append(ref new Control2());
    }
    
    Platform::String^ App1::MainPage::_Text = "";
    
    void App1::MainPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
    	grid->Children->Clear();
    	Msg->Text = Text;
    }

    Control1.h

    #pragma once
    namespace App1
    {
    	public ref class Control1 : public Windows::UI::Xaml::Controls::Control
    	{
    	public:
    		virtual ~Control1();
    	};
    }

    Control1.cpp

    #include "pch.h"
    App1::Control1::~Control1(){ MainPage::Text = MainPage::Text + "Control1"; }

    Control2.h

    #pragma once
    namespace App1
    {
    	public ref class Control2 sealed : public Control1
    	{
    	private:
    		~Control2();
    	};
    }

    Control2.cpp

    #include "pch.h"
    App1::Control2::~Control2(){ MainPage::Text = MainPage::Text + "Control2"; }

    pch.h

    #pragma once
    #include "Control1.h"
    #include "Control2.h"
    #include "MainPage.xaml.h"
    #include "App.xaml.h"

    Control2's destructor is not called. Why? And how to call the derived class destructor? If Control2 direct inheritance from Control, not Control1, no problem, why?

    Monday, March 31, 2014 4:15 AM

Answers

  • Hi,

    The documentation for C++/CX destructors here states that:

    Ref class destructors can only be declared as follows:

    • public and virtual (allowed on sealed or unsealed types)
    • protected private and non-virtual (only allowed on unsealed types)
    • private and non-virtual (allowed only on sealed types)

    No other combination of accessibility, virtualness, and sealedness is allowed.  If you do not explicitly declare a destructor, the compiler generates a public virtual destructor if the type's base class or any member has a public destructor. Otherwise, the compiler generates a protected private non-virtual destructor for unsealed types, or a private non-virtual destructor for sealed types.

    The base class Control1 has a public virtual destructor and going by documentation above, the compiler would have generated a public virtual destructor if you didn't explicitly define a destructor for the derived class. Hence, it should work if a public virtual destructor is defined explicitly in derived class.

    Sagar

    • Marked as answer by [-] Thursday, April 24, 2014 4:13 AM
    Monday, April 14, 2014 10:48 AM
    Moderator

All replies

  • Why is the destructor private?

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Monday, March 31, 2014 12:38 PM
    Moderator
  • Why is the destructor private?

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    It's C++/CX rule. Not allow destructor public in a ref class. The point is why no problem if inheritance from Windows::UI:Xaml::Controls::Control. What's wrong with class Control1?

    Control2.h

    #pragma once
    namespace App1
    {
    	public ref class Control2 sealed : public Windows::UI::Xaml::Controls::Control
    	{
    	private:
    		~Control2();
    	};
    }
    If Control2 direct inheritance from Windows::UI:Xaml::Controls::Control, not Control1, no problem, why?
    • Edited by [-] Monday, March 31, 2014 3:06 PM
    Monday, March 31, 2014 2:58 PM
  • In your derived class destructor should be virtual.

    Monday, March 31, 2014 3:12 PM
  • In your derived class destructor should be virtual.

    The derived class is sealed, so it should be not virtual. And why no problem if inheritance from Windows::UI:Xaml::Controls::Control?

    • Edited by [-] Monday, March 31, 2014 4:20 PM
    Monday, March 31, 2014 4:18 PM
  • Hi,

    The documentation for C++/CX destructors here states that:

    Ref class destructors can only be declared as follows:

    • public and virtual (allowed on sealed or unsealed types)
    • protected private and non-virtual (only allowed on unsealed types)
    • private and non-virtual (allowed only on sealed types)

    No other combination of accessibility, virtualness, and sealedness is allowed.  If you do not explicitly declare a destructor, the compiler generates a public virtual destructor if the type's base class or any member has a public destructor. Otherwise, the compiler generates a protected private non-virtual destructor for unsealed types, or a private non-virtual destructor for sealed types.

    The base class Control1 has a public virtual destructor and going by documentation above, the compiler would have generated a public virtual destructor if you didn't explicitly define a destructor for the derived class. Hence, it should work if a public virtual destructor is defined explicitly in derived class.

    Sagar

    • Marked as answer by [-] Thursday, April 24, 2014 4:13 AM
    Monday, April 14, 2014 10:48 AM
    Moderator