Is there a way to make a "virtual" variable in a C ++ base class?

I have a base class with a pointer that must be specially initialized in the constructor of all subclasses. How can I guarantee that this variable is initialized in subclass constructors? Essentially, I want the same functions as a pure virtual function, except for a pointer to an object. Is there any way to do this?

My code looks something like this:

A.hpp:

class A { protected: A(); X *pointer; }; 

B.hpp:

 class B : public A { public: B(); }; 

B.cpp:

 B::B() : A() { // how do i make sure pointer gets initialized here? } 

Is there any way to achieve this?

+8
c ++ oop c ++ 11
source share
5 answers

Change base class constructor:

 class A { protected: explicit A(X* pointer); X *pointer; }; 

And so the child should give meaning, as:

 class B : public A { public: B() : A(nullptr) {} explicit B(X* x) : A(x) {} }; 
+11
source share

Just define the arguments for the base class constructor:

 class A { protected: A(X* ptr) : pointer(ptr) {} X *pointer; }; 

Then the derived class should pass those in its ctor-initializer list:

 B::B() : A(/* value of pointer must be passed here*/) { } 
+5
source share

I would make all data members private , since protected still means that you can never change the interface. Creating a private data member also indicates how to ensure that it is provided by the derived class: give the base class the constructor for which you want to pass a suitable pointer. If you want to make sure that most of the derived classes pass in a pointer, make the base class a virtual base:

 class A { X* pointer; public: A(X* p): pointer(p) {} }; class B : public A { public: B(): A(new X) {} }; 
+3
source share

Unfortunately, current virtual tables cannot (portable) directly contain "virtual data", that is, metadata common to the class level.

You can make a virtual method by pointing to some X ...

You can also use typeinfo , i.e. typeid (in C ++ 11). For example, you can define a static hash table

 static std::unordered_map<std::typeinfo,X*> map; X* getX() { return map[typeid(this)]; }; 

Then you need to fill in the map correctly.

+1
source share

It would be enough if the base class initialized this variable itself, having a constructor with a parameter that contains the initialization value.

 class A { protected: A( X * thePointer ); X *pointer; }; 

In this case, any derived class must explicitly call the constructor of the base class and specify the required value.

 B::B() : A( thePointer ) { // how do i make sure pointer gets initialized here? } 
+1
source share

All Articles