2

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

解释为什么我需要这个:有一个抽象data类和一个manager类。该类manager包含 的派生类的对象列表(或在本例中为映射)data。我在这个问题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给管理器类的add函数,因为我不想先创建一个实例然后将其发送给管理器。

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

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

4

4 回答 4

5

您可以使用模板。在您派生的每种类型中,Data都必须定义一个“创建者”函数,其原型如下:Derived* create(). 它将在内部调用(您也可以返回 a 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())));
}

优点:数据结构代码少。

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

于 2012-10-28T14:08:07.213 回答
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");
于 2012-10-28T14:08:45.463 回答
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.

于 2012-10-28T14:09:18.727 回答
0

定义函数如下:

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

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

Manager manager;
Position posData;
//setup the posData
manager.Add("position data",posData);
于 2012-10-28T13:59:52.670 回答