C++ inheritance: determine inherited methods at runtime - c++

I have a class D that extends B which extends A. I now want to add a class C that has exactly the same interface as B but provides a different implementation. So I design it as the following:
This is not exactly what I want, as I only need an instance of D to either extend B or C and not both, however, this is only determined at runtime. The problem with the design above is of course that if I call a method in D which is implemented both in B and C, its ambiguous.
So what I would like to have is to create an instance of either B or C at runtime and then cast it into D. Every time an instance of D calls an inherited method it should use the one of its original object.
Do I need to fiddle with typeid and if/else around each method call or is there a more elegant way to do this?
class A{
virtual f1();
virtual f2();
}
class B : public virtual A{
f1();
f2();
f3();
}
class C : public virtual A{
f1();
f2();
f3();
}
class D : public B, public C{
f4(){f1(); f3)};
}
...
D* d = new D();
E* e = new E(d);
e->d->f1();
e->d->f4();
Instances of D are then passed to another class (E) which does stuff with D and therefore, I cannot modify the interface of D.

I think you're having inheritance the wrong way around, what you do is define all the methods that you want to call on what you call class D as virtual methods in class A, class B and C both have their own implementation of those methods.
Then you use a data structure of type A*, fill that with pointers to objects of type B and C and you call the methods that you need to call on all the objects in the data structure that contains pointers of type A*, the vtable mechanism will then make sure that the implementation of class B or C is used depending on what the actual object's type is.
See What is the difference between a concrete class and an abstract class?

It sounds like you just want
class A{
virtual void DoMagic() = 0;
};
class B{
virtual void DoMagic(){};
};
class D{
virtual void DoMagic(){};
};
...
bool INeedB = true;//or false
A* a;
if(INeedB){
a= new B();
}else{
a = new C();
}
a->DoMagic(); // will call the appropriate method based on the value of INeedB;
Unless D actually has behavior of its own? Then you can look at decorator pattern, and make D the decorator of an instance of B or C.
Edit: Your D class doesnt need to inherit any of A B or C at all.
class D{
D(A* aObj):a(aObj){}
void f3(){ a->f1();a->f2();}
A *a;
};
Replace A *a in above example with D d

C++ is a statically-typed language. Whatever you do with type declaration is elaborated at compile time, hence the inheritance graph of D cannot be defied at runtime.
What you probably need is to have A as a polymorphic base (with all relevant method virtual, included the destructor) for both B and C (concrete implementation of that), and D an "owner of an A", by containing an A* thet will be assigned at D construction to a new B or new C depending on input.
D destructor will call delete A, and now you have to decide about copy and assignment.
My suggestion is not to use an A*, but a std::unique_ptr (will make the owned object movable between D-s) or std::shared_ptr.
In case you need each D to have its own A, then let A to have a clone method (overridden in B and C, to return a new B and new C respectively) and call it in D's copy ctor and assign operator.

It seems like D doesn't need to inherit from A (or B or C) at all. Instead it just needs to call function in either an instance of B or an instance of C.
You can implement it something like this:
class A
{
public:
virtual void f1();
virtual void f2();
};
class B : public A;
class C : public A;
class D
{
A* b_or_c;
public:
D(A* a_pointer)
: b_or_c(a_pointer)
{}
void f3()
{
b_or_c->f1();
b_or_c->f2();
}
};
Can be used like this:
B b; // An instance of B
C c; // An instance of C
D d1(&b);
D d2(&c);
d1.f3(); // Will cause `f1` and `f2` in the object `b` to be called
d2.f3(); // Will cause `f1` and `f2` in the object `c` to be called

Related

Define a child class from an abstract parent class, which inherits from an abstract parent class

The situation is (hopefully) clear with the code. We have two (in this example pure abstract, but that isn't necessary) classes. Is this possible to define the class C? What happens to the pointer c_ptr? Do I need to delete it in the class B destructor?
class C : public B {
private:
public:
C();
~C();
int do();
};
class B : public A {
private:
C *c_ptr;
public:
B(){
c_ptr = new C();
}
~B() {
delete c_ptr;
}
virtual int do() = 0;
};
class A {
private:
public:
A();
~A();
virtual int do() = 0;
};
In short, no, this is not possible.
In your example we have the following constraints:
B is child of A
C is child of B is child of A
For every super class, there must be an object created as well. So for the instantiation of a B, there will be created an A first.
The same way for a C there will be constructed a B which will create an A first.
As C++ is a procedural language, datatypes and functions must be known BEFORE using them. However, it is not possible for the compiler to know how to build a C before knowing how to build a B and vice versa. Therefore it is not possible to do so.
However, this polymorphism structure may be accomplished by using something called Forward Declaration. Basically you tell the compiler that there is some class C which will be specified later on. Example in CompilerExplorer

Polymorphism Implementation

Let's say I have class A, class B which inherits A, and class C which also inherits A. Class C has method F, while class B does not.
class A {
//Some stuffs
};
class B : public A {
//Some stuffs.
};
class C : public A {
void F ();
};
My problem is, when I have an object that I don't exactly know what class it belongs to (it can be either B or C), I want to check that object using a pointer of class A, and if that object belongs to class C, then I would like to call method F. How do I implement those classes?
I would like something like this.
A *_a = Something;
if (_a is pointing to object of class C){
_a->F;
}
Right now, I am thinking of having that method F as a virtual method in class A, but I don't think that is a really good way of doing it, because only class C actually has it and if that is how I do it, for every method that I want in class C, I would have to add it to class A too. Is there any workaround?
If this is indeed the design you want to stick to, you first need to have a virutal base (by for example declaring the destructor virtual in A: virtual ~A() = default;, then you can simply do:
if(typeid(*_a) == typeid(C)) {
static_cast<C*>(_a)->F();
}

pointers to object and descendants in C++

I am working on a simple C++ (under Linux) project, which will have pointers to objects. I have class A, class B which extends A, and class C which extends B. Class C has a method (test) that does not exist in A or B.
Is is possible to have a single pointer 'p' that can point to an object of type A, B, and C ? How would I define that pointer?
Secondly, since a.test() doesn't exist, but c.test() does, can my generic pointer 'p' call p->test() ? Will this compile? What if at run time p points to an object of class A and I call p->test()? Is that a runtime error?
Is is possible to have a single pointer that can point to an object of
type A, B, and C ?
I assume you mean "that can either point to an A object or to B object or to a C object", right?
Yes, you can have such a pointer.
How would I define that pointer?
A*
A base-class pointer can point to objects of derived classes.
Secondly, how would I call methods of the object if the pointer can
point to A/B/C classes?
You define a virtual function in A and override it in B and C. Then, when you call the method through your A*, the language will perform dynamic dispatch, i.e. it will automatically call the right method depending on whether your A* points to an A, to a B or to a C.
Do I need to cast them before calling the methods?
No. That would pretty much defeat the purpose of virtual functions.
Here is a complete example:
#include <iostream>
class A
{
public:
virtual ~A() {} // not really needed in this program,
// but almost always needed in real code
// when a class has a virtual function
virtual void method() { std::cout << "A::method\n"; }
};
class B : public A
{
public:
virtual void method() override { std::cout << "B::method\n"; }
};
class C : public A
{
public:
virtual void method() override { std::cout << "C::method\n"; }
};
int main()
{
A a;
B b;
C c;
A* ptr = &a;
ptr->method();
ptr = &b;
ptr->method();
ptr = &c;
ptr->method();
}
Output:
A::method
B::method
C::method

C++ - Inherit from reference

I would like the class A to inherit from the class B without A having is own instantiation of B
The idea would be to create an B object on the heap (using B new) and give the pointer to A.
A would afterwards use this object to solve inheritance.
This is an example of what I would like to do:
B* b = new B();
b->myBmethode();
{
A(b);
A.myBmethode();
} // A destroyed
b->myBmethode();
delete b;
No, it is impossible (if I understood your question correctly).
3.7.5
The storage duration of member subobjects, base class subobjects and
array elements is that of their complete object
If B was created outside of A, B won't be deleted automatically after A get deleted,unless u do it explicitly,
Create an interface IA, let both A and B implement that interface. For B, just delegate all the real implementation to B.
The lifecycle of B depend on your design. When would u like it to be destroyed? You can also make B singleton if it make sense.
class IA {
virtual doA() = 0;
}
class A: public IA {
virtual doA();
}
class B: public IA {
B(A&a);
virtual doA(){
a.doA();
}
private:
A&a;
}
//init
A* a = A::getInstance();
B *b = new(*a) ;
b->doA();
You cannot inherit from a reference, but with something like this you can get half-way there:
#include<functional>
...
struct A : std::reference_wrapper<B>{
// using std::reference_wrapper<B>::reference_wrapper; // inherit constructor
};
https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper

Pointer to base class

If I have the following classes:
class A
{
...
}
class B
{
...
}
class C : public A, public B
{
...
}
and somewhere I detect that the pointer of class B that I have actually points to a class C, but a function requires a pointer to class A, what can I do to get that pointer to class A?
If you know for certain that you have a B* that points to a C object, you can use a pair of static_casts:
B* bp = new C();
C* cp = static_cast<C*>(bp);
A* ap = static_cast<A*>(cp);
The only way to cast across the inheritance hierarchy is to use dynamic_cast, which requires that the type is polymorphic (that is, your class must have at least one virtual member function; since your base class destructors should be virtual, this usually isn't a problem):
B* bp = new C();
A* ap = dynamic_cast<A*>(bp);
dynamic_cast has the added benefit that if it fails (that is, if bp doesn't actually point to a C), it returns NULL. It has the disadvantage of a slight performance cost (static_cast is effectively free at runtime).
The code
class A
{
};
class B
{
};
class C : public A, public B
{
};
int main() {
C c;
A *a = &c;
}
is valid since C is already an A, so the assignment is valid.
If C inherits from A as you have shown, then a C* pointer should be implicitly convertible to an A* pointer. Is it possible that you haven't included the declaration of class C, so that the compiler isn't aware of this inheritance relationship? Or that there is actually a different inheritance relationship than that given in your question? Some code would be helpful in diagnosing this problem.
Edit
Based on the updated version of your question:
// Converts b to type A*, but only if it is actually
// of type C; otherwise, returns NULL
A* convertBtoAviaC(B* b) {
C* c = dynamic_cast<C*>(b);
return c; // note may be NULL, if b is not a C
}