简体   繁体   中英

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

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

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(); }

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM