C++ - Inherit from reference - c++

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

Related

Call derived class' function from a base class' instance

I'm a new user of programming c++. When I don't create a derived instance by new, it calls Base::test().
So what is the difference between Base b = d and Base* b1 = new Derived() ?
Base class
#include <iostream>
class Base
{
public:
virtual void test() { std::cout << "Base::test()" << std::endl; };
};
Derived class
#include "Base.h"
class Derived : public Base
{
public:
void test() { std::cout << "Derived::test()" << std::endl; };
}
main.cc
#include "Derived.h"
int main()
{
Derived d;
d.test();
Base b;
b = d;
b.test(); // why called Base::test() ?
Base* b1 = new Derived();
b1->test();
delete b1;
return 0;
}
Derived d;
d.test();
Base b;
b = d;
b.test(); // why called Base::test() ?
You created a Derived object d and Base object b. And later assigned b=d; Here object slicing is happening. After the assignment b has only Base part of the Derived class info in hand. So when you call b.test() it will call Base::test() instead Derived::test() function.
Base* b1 = new Derived();
b1->test();
delete b1;
Here you dynamically created a Derived class object in heap and returned the pointer of that object to Base class pointer. Here pointer is nothing but the memory address holding the Derived class object. And when you call b->test(), system internally identify the type of the object dynamically and it is returned as Derived. So it will call Derived::test() function.
Because that's not how polymorphism is implemented in C++.
This:
Base b;
b = d;
the second statement calls an assignment operator of b, i.e. b is still the same object b of class Base (except perhaps the data is now different, but the set of methods, i.e. the type is still Base).
You need to operate on pointers instead of references, because references cannot be changed and they are not changed.
You have mesh between two important concept in c++.
Run time polymorphism
Object Slicing
In c++ run time polymorphism is achieved using base class pointer with the help of virtual function. Since actual type of object is decided at run time. As we know base class pointer can store object of derived class. And then call to any function invoke call to derived class function(if base is virtual).
In you case you are assigning object of derived class to object of base class. This is Object slicing.

C++ - How to create factory methods if class does not know about another class?

Let's say I have two base classes: A and B. They are both defined in different libraries. A knows about B but not the other way around.
Let's say I have some derived classes as well: C derives from A and D derives from B
I always create an object of type B first before creating an object of type A. So for example:
B *b = B::CreateB(some object); // static factory method that either creates either B or D.
...
A *a = A::CreateA(some object) // static factory method that either creates A or C
Ideally, I would like to be able to do this:
B *b = B::CreateB(some object); // static factory method that either creates either B or D.
...
A *a = b->CreateA() // dynamic factory method that either creates A or C based on the type of b.
The problem is that B is in a common library that does not know anything about the library A is in (and I don't want to change that).
What I would like to avoid is having to do the same work for determining what type to create two times. The "some object" that is passed into the methods is a complex object that I need to dig into in order to find out which type to create. It's not as simple as saying "if some object is this, create B, else create D". I know that I could have the base class store what type it is and use that info when creating A, but then that would defeat the purpose of having these class structures. Is there a cleaner way to create A based on what type B is?
Maybe solution is to use visitor pattern.
class B;
class D;
class BVisitor {
public:
virtual void visit(B&);
virtual void visit(D&);
};
class B {
public:
virtual void accept(BVisitor& bVisitor) { bVisitor.visit(*this); }
};
class D: public B {
public:
virtual void accept(BVisitor& bVisitor) { bVisitor.visit(*this); }
};
So, your B/D library does not know nothing about A/c classes.
Then use the real type information of B in this way:
class AFactory : public BVisitor {
public:
A* getCreatedObject() { return a; }
void visit(B& b) { a = new A(); }
void visit(D& d) { a = new D(); }
private:
A* a = nullptr;
};
A* A::createA(B& b) {
AFactory af;
b.accept(af);
return af.getCreatedObject();
}
This is just a scheme of solution. Pass in constructor of AFactory whatever extra-data you need.

C++ inheritance: determine inherited methods at runtime

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

How to prevent static instances of simple C++ class objects while allowing dynamic instances

I know how to prevent dynamic instantiation of a class in C++. (Define my own 'new' operator) But is there a simple way to prevent static instantiation so that I force dynamic instances? That is, how do I do this... (This is not a derivable abstract base class. Just a simple class)
class B {
};
B b; // how do I prevent this without using friends or some derived class trick
B* b;
b = new B; // still want to be able to do this.
You can prevent it by making the c'tor private:
class B {
B() {}
public:
static B* alloc() { return new B; }
};
Instead of b = new B; you will do: b = B::alloc();
You can prevent it by making the c'tor private:class B { ...
}; Instead of b = new B; you will do: b = B::alloc();
But this is only half of the truth, right? I could still do an
static B* b = B::alloc();
yielding a pointer to a statically (i. e. created before execution of main()) object - i.e. this is more or less a static object, it only is located on the heap. Is there a way to prevent this?

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
}