如何将类作为参数传递

时间:2012-10-28 13:54:18

标签: c++ class function types parameters

在C ++中有没有办法将类型(例如类)作为参数传递给函数?

解释为什么我需要这个:有一个抽象的data类和一个manager类。 manager类包含data的派生类对象的列表(或在本例中为映射)。我在this question的答案中提到了unique_ptr

class Data{}; // abstract

class Manager
{
    map<string, unique_ptr<Data>> List;
};

现在想象一下,我想向经理添加一个新的data存储空间。

class Position : public Data
{
    int X;
    int Y;
}

我如何告诉经理创建该类型的对象并将unique_ptr引用给它?

Manager manager;
manager.Add("position data", Position);

在这种情况下,我需要将类Position传递给manager类的add函数,因为我不想首先创建一个实例然后将它发送给manager

然后,我怎样才能将该类的对象添加到List

我不确定是否有办法在C ++中这样做。如果不能轻易完成,我真的希望看到一个解决方法。非常感谢!

4 个答案:

答案 0 :(得分:5)

您可以使用模板。在源自Data的每种类型中,您必须定义“创建者”函数,该函数具有以下原型:Derived* create()。它将在内部调用(您也可以返回unique_ptr,但这需要更多内存。)

例如:

struct Position: public Data
{
    // ...
    static Position* create()
    {
        return new Position();
    }
};

Add方法将是:

template<typename D>
void Add(String str)
{
    List.insert(std::make_pair(str, std::unique_ptr<Data>(D::create())));
}

然后你就这样使用它:

Manager manager;
manager.Add<Position>("position data");

修改

您还可以使用此create方法摆脱Add函数:

template<typename D>
void Add(String str)
{
    List.insert(std::make_pair(str, std::unique_ptr<Data>(new D())));
}

优点:数据结构代码中的代码更少。

不方便:数据结构对其构建方式的控制较少。

答案 1 :(得分:3)

这样的事情:

class Manager
{
 public:
  template <typename T>
  void addData(const std::string& title)
  {
    List.insert(std::make_pair(title, std::unique_ptr<Data>(new T));
  }
 private:   
  map<string, unique_ptr<Data>> List;
};

然后

Manager manager;
manager.addData<Position>("position data");

答案 2 :(得分:1)

使用unique_ptr意味着承诺使用动态分配的对象。 (不完全正确:你可以提供一个不调用delete的自定义删除器,但它会成为该类型的一部分;这意味着你将承诺使用 - 动态分配对象。)

void Manager::Add(String title, unique_ptr<Data> d) {
    List[title] = d;
}

将其命名为:

Manager manager;
unique_ptr<Data> pos(new Position);
// Set it up
manager.Add("position data", pos);

注意:如果您希望能够对数据对象执行任何操作,您可能希望在class Data中声明至少一个虚拟函数。

答案 3 :(得分:0)

将功能定义如下:

void Manager::Add(String title,Position pos){ /*snip*/ }

然后您可以使用以下功能:

Manager manager;
Position posData;
//setup the posData
manager.Add("position data",posData);