Home > Software engineering >  Pointers to an anonymous and named Inner Derived Class of a Base::Inner Class have different behavio
Pointers to an anonymous and named Inner Derived Class of a Base::Inner Class have different behavio

Time:01-28

I have a Base Class with an Inner Class with two pointers to the Inner Class and one Inner Class data member.

I next define a Derived Class with two Inner Derived Classes, one anonymous, one named. The constructor for the Derived class sets each of the Base Class pointers to one of the Inner Derived Classes.

Finally, I create a Derived Grandchild Class. In the class constructor I use the pointers to print a data object value from the Base Class's Inner Class. The pointer to the anonymous class works, but the pointer to the named class appears to be uninitialized. What's happening here?

class Base {
public:
    class Inner {
    public:
        int test_int = 1;
    };

    Inner* inner_class_ptr_to_anonymous_inner_derived_class;
    Inner* inner_class_ptr_to_inner_derived_class;
};

class Derived : public Base {
public:
    class Inner_Derived : public Base::Inner {};
    class : public Base::Inner {}anonymous_inner_derived;
    Derived()
    {
        Inner_Derived inner_derived;
        inner_class_ptr_to_inner_derived_class = &inner_derived;

        inner_class_ptr_to_anonymous_inner_derived_class = &anonymous_inner_derived;
    }
};

class Derived_GrandChild : public Derived {
public:
    Derived_GrandChild() {  
        std::cout << "Anonymous Inner Derived Class test_int = " << inner_class_ptr_to_anonymous_inner_derived_class->test_int << std::endl;
        std::cout << "Inner Derived Class test_int = " << inner_class_ptr_to_inner_derived_class->test_int << std::endl;
    }
};

Output:

Anonymous Inner Derived Class test_int = 1

Inner Derived Class test_int = -858993460

CodePudding user response:

The object inner_derived is a local variable of the constructor Derived

Derived()
{
    Inner_Derived inner_derived;
    inner_class_ptr_to_inner_derived_class = &inner_derived;

    inner_class_ptr_to_anonymous_inner_derived_class = &anonymous_inner_derived;
}

that will not be alive after exiting the constructor, So the pointer inner_class_ptr_to_inner_derived_class will be invalid after execution of the constructor. Dereferencing the pointer

std::cout << "Inner Derived Class test_int = " << inner_class_ptr_to_inner_derived_class->test_int << std::endl;

invokes undefined behavior.

As for the variable anonymous_inner_derived then it is a data member of the class Derived.

class : public Base::Inner {}anonymous_inner_derived;

Pay attention to that in C there are only anonymous unions. There are no anonymous classes with class key class or struct. In your code you are using an unnamed class.

CodePudding user response:

Thanks to NathanOliver and Vlad for the quick answers to my problem. The solution was to just to make Inner_Derived inner_derived an object of the Derived class

class Base {
public:
    class Inner {
    public:
        int test_int = 1;
    };

    Inner* inner_class_ptr_to_anonymous_inner_derived_class;
    Inner* inner_class_ptr_to_inner_derived_class;
};

class Derived : public Base {
public:
    class Inner_Derived : public Base::Inner {};
    class : public Base::Inner {}anonymous_inner_derived;
    Inner_Derived inner_derived;
    Derived()
    {
        inner_class_ptr_to_inner_derived_class = &inner_derived;

        inner_class_ptr_to_anonymous_inner_derived_class = &anonymous_inner_derived;
    }
};

class Derived_GrandChild : public Derived {
public:
    Derived_GrandChild() {  
        std::cout << "Anonymous Inner Derived Class test_int = " << inner_class_ptr_to_anonymous_inner_derived_class->test_int << std::endl;
        std::cout << "Inner Derived Class test_int = " << inner_class_ptr_to_inner_derived_class->test_int << std::endl;
    }
}

Output:

Anonymous Inner Derived Class test_int = 1

Inner Derived Class test_int = 1

  • Related