Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what happens if I cast (a pointer to class A) to (a pointer to its subclass B) in c++

Tags:

c++

pointers

A has a static function A::create() that creates an instance of A, does some initialization, and returns a pointer to it. I want to create a subclass of A and have a similar create() func:

class B : public A {
public:
    static B* create();
    int val;
    //...
}

in this B::create() function I have to do the following:

B* B::create() {
    auto b = (B*)A::create();
    b -> val = 0;
    //...
    return b;
}

Is this the right way to do it? What will happen after the cast?

Follow-up: A has a protected/private constructor, How should I write B::create(), or B's constructor? I do want the vars inherited from A to have the same values as those created by A::create() would have

like image 453
snickers2029 Avatar asked May 03 '15 06:05

snickers2029


People also ask

What happens if you assign a pointer to another pointer?

Pointer assignment between two pointers makes them point to the same pointee. So the assignment y = x; makes y point to the same pointee as x . Pointer assignment does not touch the pointees. It just changes one pointer to have the same reference as another pointer.

Can a pointer point to another class 1 point?

It is true that a pointer of one class can point to other class, but classes must be a base and derived class, then it is possible. To access the variable of the base class, base class pointer will be used.

Why a pointer to a subclass may not point to its base class?

The actual reason is - a derived class has all information about a base class and also some extra bit of information. Now a pointer to a derived class will require more space and that is not sufficient in base class. So the a pointer to a derived class cannot point to it.

Can a pointer declared as a pointer to a base class can be used to point to any class derived from that base?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.


2 Answers

The cast won't do anything sensible unless A::create() returns a pointer to a B object. If A::create() returns a pointer to an object which isn't a B you have undefined behavior.

In C++ you deal with initialization of objects using constructors: the initialization of base classes is inherited and each derived can do whatever custom initialization it needs to do. Your B::create() would just return a suitably constructed object:

B::B()
    : A() // initialize base
    , val(0) {
        // other initialization
}
B* B::create() { return new B(); }
like image 114
Dietmar Kühl Avatar answered Oct 11 '22 23:10

Dietmar Kühl


You could make class B a friend of A like this

class A {
public:
    static A* createA();
    int varA;

private:
    friend class B;    // Make B a friend so that B can use private constructor of A

    A()
    {
        cout << "In A constructor" << endl;

        varA = 5;  // Initialize members of A here
    }
};

A* A::createA()
{
    return new A;
}

class B : public A {
public:
    static B* createB();
    int varB;
private:
    B()
    {
        cout << "In B constructor" << endl;

        varB = -5;  // Initialize members of B here
    }
};

B* B::createB()
{
    return new B;
}

int main()
{
    cout << "Create A" << endl;
    A* x=A::createA();
    cout << "x->varA is " << x->varA << endl;
    cout << endl;

    cout << "Create B" << endl;
    B* y=B::createB();
    cout << "y->varA is " << y->varA << endl;
    cout << "y->varB is " << y->varB << endl;
    cout << endl;

    delete x;
    delete y;
}

When a new B is made, the constructor of A get called automatically and the members of A will be initialized.

Output is:

Create A
In A constructor
x->varA is 5

Create B
In A constructor
In B constructor
y->varA is 5
y->varB is -5

Another way is to make the constructor of A protected instead of private.

like image 29
Support Ukraine Avatar answered Oct 11 '22 23:10

Support Ukraine