Static pointer in C ++ inheritance

I am confused, why p->a()is it causing B::a()? Is there a paragraph somewhere in the C ++ documentation / standard that describes this behavior well?

#include <iostream>
using namespace std;

class A {
  public:
  A() { cout << "A ctor" << endl; a_instance = this; }
  static A *get_instance() { return a_instance; }
  static A *a_instance;
  void virtual a() { cout << "From base class" << endl; }
};

class B : public A {
public:
  B() { cout << "B ctor" << endl; b_instance = this; }
  static B *get_instance() { return b_instance; }
  static B *b_instance;
  void virtual a() { cout << "From derived class" << endl; }
};

A *A::a_instance = 0;
B *B::b_instance = 0;

main()
{
    cout << "Create A" << endl;
    A ab;
    cout << "Create B" << endl;
    B abc;
    B *ptr = B::get_instance();
    A *p = A::get_instance();

    cout << "Called from A object type" << endl;
    if (p) {
       p->a();
    }
}
+4
source share
4 answers

When you create a variable abc, the Aconstructor sets a_instanceto this instance. Despite being pa pointer to A, since the instance points to B, it correctly calls B::a().

To fix this behavior, you can use the following:

A* A::get_instance()
{
    static A a;
    return &a;
}

B* B::get_instance()
{
    static B b;
    return &b;
}  

and remove all the code associated with a_instanceand b_instance.

+6

B A. a_instance, .

. , .

+5

, , , A, , this. A, :

A() { /* ... */ a_instance = this; }

, B, B , A - a_instance this B, .. a_instance B.


, getInstance:

class A
{
public:
    static A* getInstance() {
        static A s;                 // <-- instantiated upon first call
        return &s;
    }
    void virtual foo() { std::cout << "From base class" << std::endl; }

protected:
    A() { }                         // <-- protected constructor
    ~A() { }
    A(const A&);                    // <-- protected copy constructor
    A& operator=(const A&);         // <-- protected assignment operator
};

B:

class B : public A
{
public:
    static B* getInstance() {
        static B s;                 // <-- instantiated upon first call
        return &s;
    }
    void virtual foo() { std::cout << "From derived class" << std::endl; }

protected:
    B() { }                         // <-- protected constructor
    ~B() { }
    B(const B&);                    // <-- protected copy constructor
    B& operator=(const B&);         // <-- protected assignment operator
};

:

int main() {
    A::getInstance()->foo();
    B::getInstance()->foo();
}

:

+4

B A...

+2

Source: https://habr.com/ru/post/1533360/


All Articles