Is it possible to call the constructor of a superclass, two classes from the current class in C ++

I have three classes that inherit as follows:

Class_A Class_B : public Class_A Class_C : public Class_B 

Class_A contains the constructor:

 public: Class_A(const char *name, int kind); 

Class_B does not contain this constructor.

In Class_C I want to call the constructor of class_A. Sort of:
Class_C(const char *name, int kind) : Class_A::Class_A(name,kind) { }

The problem is that I cannot add an intermediate constructor to Class_B , because Class_B is the generated code, which is restored every time I make it clean. Therefore, I cannot make any lasting changes to Class_B . Needless to say, the above constructor line in Class_C gives error: "type 'Class_A' is not a direct base of ' Class_C '".

Is there any way I can call the Class_A constructor in a subclass of Class_C without requiring the same constructor type in Class_B ?

+6
source share
7 answers

If you cannot change the code generating B , you're out of luck, AFAIK. But if class A contains such a constructor, maybe you can get away with adding a simple member function that sets these two variables and calls it from the constructor of C ? It may not be as effective as it is, but at least it works.

+4
source

If you can make a base class a virtual base class, you can do this, since virtual databases must always be uninitialized in the outermost constructor. If you cannot change the way Class B inherits from A, you can always do this:

 RealClassA ClassA : public virtual RealClassA ClassB : public ClassA ClassC : public ClassB 

Then in the ClassC constructor, you can directly call RealClassA(...) .

Usually this virtual inheritance feature is a real pain, but actually it can help you here.

+1
source

You are probably packed (assuming you cannot change the generation of class B), but if there are constructors for B that are templates, then you can specialize one (for a unique dummy class) and create your own constructor with any building a base class A that you like ....

Otherwise, a less efficient, obvious, safe and clean approach is to use A operator= (if any) to get the value you need ...

 C c; c = A(x, y); 

If those fields A can only be set at build time, then this is more complicated.

(Step instantly and deep into the terrible land of Undefined Behavior, you can call the destructor and then place it new , but the life span is intended to cover Bs and Cs. The almost obvious risk is that A created something like a value allocated by a bunch that B or C already contains a pointer and may try to use it after the destructor releases it.)

+1
source

The only possibility for Class_B is to actually inherit from Class_A ; in this case, the constructor for Class_A will be called from the derived class itself. But since this also involves changing the code generator or entering the code generator, you can change it to add an additional constructor to Class_B .

If you really cannot change the code generator or input it in such a way as to lead to the generation of an additional constructor, but you can change Class_A and Class_C , then there are two possible solutions:

The simplest is to use delayed initialization; add a Class_A function that takes the appropriate parameters and does initialization after the constructor completes. While the simplest one, this method can be used only if Class_A can be used for support as well as if all members of the support are Class_A with semantics, so after assignment it has the same result as building using arguments you you give (i.e. there are no reference members, no non-communicable members, no const , etc.). Alternatively, you can put all the functionality (or at least data members) of Class_A in a separate class and have Class_A derive from this class practically. Class_C will then call the constructor of this new class.
+1
source

If B is generated, change the generator, otherwise you are doomed.

Depending on what B does, it may be a solution to change your design to have C output from A and B directly (if A is your container class and B is the processing class). To do this, you may need a pattern B. If B must act on the members of A, you can still point the pointer A to the constructor of B ...

0
source

You can add a constructor for Class_B that has the same signature as ctor Class_A , and then let Class_C call this in ctor.

In addition, the ctor class initialization list could not set values ​​for members in the base class (regardless of whether they are private protected or public ). You must use the 'ctor base class to install them.

0
source

By language, it is impossible to access the designers of the immediate database.

By the way, if Class_A signature of the constructor,

 Class_A(const char *name, int kind); 

then Class_B must have some constructor that will contain the Class_A constructor of this type. Otherwise, it will give a compiler error.

The only way to get rid of this error is to provide default arguments for Class_A::Class_A(...) .

0
source

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


All Articles