Reputation: 103
Let's say we have the following classes:
class A
{
public:
A() {}
};
class B
{
public:
B() {}
virtual ~B() {}
};
template<typename T>
class BB: public B
{
public:
BB() {}
};
class C: public A, public BB<bool>
{
public:
C() {}
};
class D: public A, public B
{
public:
D() {}
};
Do casting a C
object to class type D
is possible/allowed/safe ? This in order to access non templated stuff and use polymorphism.
I tried and got the error no matching function for call to 'D::D(C&)'
.
Do adding the constructor D::D(C& c): A(c), B(c) {}
will suffice to do so ?
Please note that I am currently using C++11 and I must stick to it, thus I need a compatible solution, however there may be better solutions with later standards so you may still share those for the sake of my knowledge.
Edit: after reading the comments, here are some further explaination to my problem
The definition of B
and BB
cannot be changed, see it like classes from an API that can't modified.
Casting directly is calling the constructor and creates an new object, that's not what I want, thus it requires Indirection as mentionned in the answers.
Given this other class:
class Cbis: public A, public BB<float>
{
public:
Cbis() {}
};
The only purpose of the class D
would be to allow to store C
and Cbis
references in the same container and be able to access methods from both A
and B
classes.
In the end, it may not be possible at all as, even with common ancestors, as D
is not a base class.
Therefore, what could be the alternatives ? Besides storing in two separate containers one based on A
pointers and the on B
pointers.
Upvotes: 2
Views: 92
Reputation: 238371
Do casting a C object to class type D is possible/allowed/safe ? This in order to access non templated stuff and use polymorphism.
Indirection is required to gain runtime polymorphism.
If the C
object is referred indirectly, then you can dynamic_cast
the reference (or pointer) to a D
reference (pointer) since they have common ancestors (that have virtual functions). The cast succeeds if and only if that C
object is a base of a derived class that also inherits D
. dynamic_cast
will safely fail if this is not the case.
Do adding the constructor
D::D(C& c): A(c), B(c) {}
will suffice to do so ?
Adding a converting constructor will make the type (implicitly if the constructor isn't explicit
) convertible to another. With such constructor the conversion can be done explicitly using static_cast
. It is important to understand that the result of the conversion (from C
to D
) is no longer a C
object.
Upvotes: 4
Reputation: 390
Yes, it is possible using reinterpret_cast, link.
Safe? Not at all! reinterpret_cast tells the compiler to ignore everything and simply treat object pointer by Obj2 as an object of C, it worked in this example because the byte happened to be aligned, simply changing the order of functions or adding others will cause it to crash.
Upvotes: 1