Reputation: 39
I'm an C++ beginner, please help me. I can't use template class as the constructor' s parameter. xcode shows 'No matching constructor for initialization of 'Work'' error. The whole source code below, any one can fix this?
#include <iostream>
class Base {
public:
virtual void hello_world() const {
printf("Base::hello_world()\n");
};
};
class Derived : public Base {
public:
void hello_world() const {
printf("Derived::hello_world()\n");
};
};
template<class T>
class Templ {
public:
Templ(const T &t) : _value(t) {}
const T& getValue() const{
return _value;
}
private:
const T &_value;
};
class Work {
public:
Work(const Templ<Base*> &base) : mBase(base) {}
void working() {
mBase.getValue()->hello_world();
}
private:
const Templ<Base*> &mBase;
};
int main(int argc, const char * argv[]) {
Templ<Base*> base(new Base());
//OK
Work w_base(base);
Templ<Derived*> derived(new Derived());
//error: No matching constructor for initialization of 'Work'
Work w_derived(derived);
return 0;
}
Upvotes: 1
Views: 263
Reputation: 45434
In C++, this would look like this
struct Base
{
virtual ~Base() {} // enable descruction of base through pointer to Base
virtual void hello_world() const
{ std::cout<<"Base::hello_world()\n"; }
};
struct Derived : Base
{
void hello_world() const override
{ std::cout<<"Derived::hello_world()\n"; }
};
struct work
{
work(const Base*p)
: ptr(p) {}
void working() const
{ ptr->hello_world(); }
private:
std::unique_ptr<const Base> ptr;
};
int main()
{
Work w_base(new Base);
Work w_derived(new Derived);
w_base.working();
w_derived.working();
}
Note the following
virtual
destructor of Base
ensures that a derived class is properly destructed from a pointer to Base
, so that std::unique_ptr<>
works correctly.override
keyword ensures that we actually implement a virtual method.std::unique_ptr<>
avoids the Templ
class. Morever, its destructor will automatically and correctly destroy the pointed-to object, avoiding the memory leak of your code.return 0
is not required for int main()
, but automatically generated.Upvotes: 0
Reputation: 180630
Work w_derived(derived);
is never going to work as Work
expects a Templ<Base*>
. A Templ<Base*>
and a Templ<Derived*>
are two different, distinct types. Just a like a std::vector<int>
is not the same as a std::vector<std::complex>
.
What you can do though is create a Templ<Base*>
from a pointer to a Dervied
and then create a Work
with that. Something like
Templ<Base*> derived(new Derived());
Work w_derived(derived);
Also as pointed out in the comments since you are using polymorphism you need to have a virtual destructor in the base class. If the destructor is not virtual then only the base class destructor will run and you will your object will not be properly destructed.
Upvotes: 1