Reputation: 995
I have a templated class hierarchy structured as follows: AbstractClass -> BaseClass -> DerivedClass.
AbstractClass serves as an interface.
I am including my code below:
#include <cstdlib>
#include <iostream>
using namespace std;
//AbstractClass
template <class T, class K>
class AbstractClass
{
public:
virtual void someMethod() const =0;
};
//end AbstractClass
//BaseClass
template <class T>
class BaseClass:AbstractClass<T,int>
{
public:
BaseClass();
BaseClass(const BaseClass<T>&);
void someMethod() const;
};
template <class T>
BaseClass<T>::BaseClass()
{}
template <class T>
BaseClass<T>::BaseClass(const BaseClass<T>& baseClass)
{}
template <class T>
void BaseClass<T>::someMethod() const
{}
//end BaseClass
//DerivedClass
template <class T>
class DerivedClass:BaseClass<T>
{
public:
DerivedClass();
//DerivedClass(const DerivedClass<T>&);
};
template <class T>
DerivedClass<T>::DerivedClass()
{}
/*
template <class T>
DerivedClass<T>::DerivedClass(const DerivedClass<T>& derivedClassClass)
{ BaseClass<T>::BaseClass(derivedClassClass);}
*/
//end DerivedClass
int main(int argc, char *argv[])
{
BaseClass<double> baseClass;
DerivedClass<double> derivedClass;
baseClass.someMethod();
derivedClass=(DerivedClass<double>)baseClass;
system("PAUSE");
return EXIT_SUCCESS;
}
I need to cast a BaseClass instance to a DerivedClass instance. I try to do this by
`derivedClass=(DerivedClass<double>)baseClass;`
but I get the following error:
no matching function for call to `DerivedClass<double>::DerivedClass(BaseClass<double>&)'
candidates are: DerivedClass<double>::DerivedClass(const DerivedClass<double>&)
.
The error occurs both with DerivedClass's copy constructor
DerivedClass(const DerivedClass<T>&);
implemented and not implemented. In the code above I have commented it in order to make it easeier for you to make test with and without.
What am I doing wrong? Can somebody have a look into it?
I am using dev-cpp 4.9.9.2 and c++'98.
Upvotes: 1
Views: 1003
Reputation: 308528
As you can see by the error message, the cast isn't casting the object, it's making a copy via the copy constructor. Since you didn't provide a copy constructor that takes a reference to BaseClass
, it fails.
To make a cast without going through a copy constructor, you need to cast a pointer or reference to the object, not the object itself. Casting a reference/pointer to a more derived one is only valid if you know that the actual type of the object is what you are casting it to; anything else would be undefined behavior.
Upvotes: 1
Reputation: 206747
Let's take a simple illustrate why casting a base class to a derived class is a problem for the compiler.
struct Base
{
int i;
};
struct Derived : public Base
{
float f;
};
Base b;
b.i = 10;
Derived d = (Derived)b;
When you do that, the compiler has no way of figuring out how to initialize the parts of d
that are not in b
. For Derived
, it is just the member data f
. For other, more complex, derived classes, there can be a lot more data that need to be initialized.
However, if you had:
struct Derived : public Base
{
Derived(Base const& b) : Base(b), f(0f) {}
float f;
};
Then you can just use:
Base b;
b.i = 10;
Derived d = b;
The compiler sees that you have provided a way to construct a Derived
from a Base
and is able to use that constructor to construct d
.
Upvotes: 1
Reputation: 1299
In C++ casting objects is always about pointers which you try to avoid in your main(). You can try the code below for example in your main to see how it should be:
BaseClass<double>* baseClass = new BaseClass<double>();
DerivedClass<double>* derivedClass;
baseClass->someMethod();
//derivedClass=(DerivedClass<double>)baseClass;
derivedClass = dynamic_cast<DerivedClass<double>*>(baseClass);
delete baseClass;
return 0;
You can find some interesting reading about casting in C++ right here:
http://www.cplusplus.com/doc/tutorial/typecasting/
Upvotes: 0