“Holder”模板类用于存储不同的对象类型。带参数和不带参数的构造函数

时间:2015-08-06 11:39:47

标签: c++ templates inheritance

我正在实现一个模板类“Holder”,后来应该专门用于包含不同类的对象。 Holder将对象存储为属性。当在构造函数中存储需要参数的对象时,holder类在实例化时失败:

#include <iostream>

template<class _StoredClass>
class Holder 
{
  protected:

    _StoredClass storedObject;

  public:

    void setData(_StoredClass toStore) { storedObject = toStore; }

    _StoredClass getData() { return storedObject; }

};

class DummyClass 
{
  private:
    int id;
  public: 
    DummyClass(int myId)
    {
      id = myId;
    }
    void welcome()
    {
      std::cout << "This is a method of the class to which the template fits" << std::endl;
    }
};

class DummyHolder : public Holder<DummyClass> {
  public: 
    void hello()
    {
      std::cout << "You successfully created a class that inherited from a specialized template. Hello!" << std::endl;
    }
};

int main () {
  DummyClass dummyObject(1);
  dummyObject.welcome();
  DummyHolder dummyHolder;  //error: no matching function for call to ‘DummyClass::DummyClass()’
  dummyHolder.hello();
  dummyHolder.setData(dummyObject);
}

如何实现Holder类,以便它还可以存储带参数的构造函数,但不向模板添加新参数?在实例化类“Holder”时是否可以避免实例化类的属性?实际上,此对象稍后将由“setData”方法提供。因此实例化是不必要的。

我不想将构造函数的参数包含在模板的另一个参数中,因为该更改将涉及为每个特化提供此参数,通常不需要此参数。

2 个答案:

答案 0 :(得分:2)

您可以创建模板构造函数:

template<class _StoredClass>
class Holder 
{
  protected:
    _StoredClass storedObject;

  public:

    template <typename ... Ts>
    Holder(Ts&&...args) : storedObject(std::forward<Ts>(args)...) {}

    void setData(const _StoredClass& toStore) { storedObject = toStore; }
    const _StoredClass& getData() const { return storedObject; }

};

DummyHolder更新为

class DummyHolder : public Holder<DummyClass>
{
public: 
    DummyHolder(int i) : Holder<DummyClass>(i) {}

    void hello()
    {
      std::cout << "You successfully created a class that inherited from a specialized template. Hello!" << std::endl;
    }
};

主要是:

DummyHolder dummyHolder(42);

答案 1 :(得分:1)

在实例化类“Holder”时是否可以避免实例化类的属性?

您可以使用boost::optional

#include <boost/optional.hpp>
template<class StoredClass>
class Holder 
{
protected:
    boost::optional<StoredClass> storedObject;
public:
    void setData(const StoredClass& toStore) { storedObject = toStore; }

    StoredClass getData() { return *storedObject; }

};