C ++模板<base class =“”和=“”derived =“”class =“”/>

时间:2016-08-11 12:59:04

标签: c++ templates

我是C ++初学者,请帮助我。 我不能使用模板类作为构造函数的参数。 xcode显示'没有用于初始化'工作''错误的匹配构造函数。 下面的整个源代码,任何人都可以解决这个问题吗?

#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;
}

2 个答案:

答案 0 :(得分:1)

Work w_derived(derived);永远不会起作用,因为Work期望Templ<Base*>Templ<Base*>Templ<Derived*>是两种不同的不同类型。就像std::vector<int>一样与std::vector<std::complex>不一样。

您可以做的是从指向Templ<Base*>的指针创建Dervied,然后使用该Work创建Templ<Base*> derived(new Derived()); Work w_derived(derived); 。像

这样的东西
{{1}}

Live Example

正如您在使用多态性时在评论中指出的那样,您需要在基类中使用虚拟析构函数。如果析构函数不是虚拟的,那么只会运行基类析构函数,并且您的对象将无法正确销毁。

答案 1 :(得分:0)

在C ++中,这看起来像这样

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();
}

请注意以下内容

  1. virtual Base析构函数可确保从指向Base的指针正确销毁派生类,以便std::unique_ptr<>正常工作。
  2. override关键字确保我们实际实现虚拟方法。
  3. std::unique_ptr<>的使用避免了Templ类。更重要的是,它的析构函数会自动并正确地销毁指向的对象,避免代码的内存泄漏。
  4. {li> return 0不是int main()所必需的,而是自动生成的。