12

I have a template class named Cell as follows:-

template<class T>class Cell
{
    string header, T data;
}

Now I want another class Named Row. Row will have a vector named Cells such that I can add both Cell and Cell type elements to that vector. Is it possible?

If so, how can I do that? Thanks in advance.

4

4 回答 4

24

使用您提供的额外细节,前两个答案将不起作用。您需要的是一种称为单元变体的类型,然后您可以拥有这些类型的向量。例如:-

enum CellType
{
  Int,
  Float,
  // etc
};

class Cell
{
  CellType type;
  union
  {
    int i;
    float f;
    // etc
  };
};

class Vector
{
  vector <Cell> cells;
};

然而,添加新类型是一件很痛苦的事情,因为它需要大量代码来维护。另一种方法可以使用具有公共基类的单元格模板:-

class ICell
{
  // list of cell methods
};

template <class T>
class Cell : public ICell
{
  T data;
  // implementation of cell methods
};

class Vector
{
  vector <ICell *> cells;
};

这可能会更好,因为您最初更新的代码较少以添加新的单元格类型,但您必须在单元格向量中使用指针类型。如果您按值存储单元格vector <ICell>,那么您将由于对象切片而丢失数据。

于 2013-04-25T09:26:37.997 回答
12

这在 C++ 中不可能,但在 Java/Python 中可能是因为:在 C++ 向量中,STL 容器的存储(由 vector::data() 返回)包含顺序打包的所有对象实例。其中每个元素必须具有相同的大小。这使得寻址快速方便。因此,假设您定义了一个模板类 A,

template <class T>
class A{
  int id;
  T obj;
};

它的大小将取决于模板变量“T obj”。推送不同模板类型 T 的同一个类 A 会使向量中的每个元素具有不同的大小,因此,这是不可能的。唯一的方法是使用基类的 shared_ptr 或 unique_ptr 的向量。C++11 和 Boost 都支持 shared_ptr 和 unique_ptr。每个派生类元素可以有不同的模板类型。这样,当基类指针的析构函数被调用时,派生类的析构函数就会被调用。例如,

#include <memory>
#include <vector>
#include <iostream>
#include <string>

using namespace std;

class A{};

template <class T>
class AImpl : public A{
public:
    T obj;
    AImpl(T _obj):obj(_obj){}
    ~AImpl(){
        cout << "Deleting " << obj << endl;
    }
};

int main(int argc, char** argv)
{
    AImpl <string>* a1 = new AImpl <string> ("string1234");
    AImpl <int>* a2 = new AImpl <int> (1234);
    AImpl <double>* a3 = new AImpl <double> (1.234);
    vector <shared_ptr<A>> As;
    As.push_back(shared_ptr<A>(a1));
    As.push_back(shared_ptr<A>(a2));
    As.push_back(shared_ptr<A>(a3));
}

请记住使用 -std=c++11 进行编译以启用 C++11。

输出:

Deleting string1234
Deleting 1234
Deleting 1.234

你得到你想要的!:)

在 Java/Python 中,每个类对象变量实际上都是一个指针,因此,A 的 Java 数组或 A 的 Python 列表等效于 A 的指针的 C++ 数组。因此,无需显式创建即可获得基本相同的功能shared_ptrs。

于 2016-04-13T03:43:33.867 回答
6

另一个答案很好,但您可能想要:

template<class T>
class Row
{
private:
    class Cell {
        string header;
        T data;
    }

    std::vector<Cell> cells;
    ...
}
于 2013-04-25T09:14:11.167 回答
4

像这样的东西?

template<class T>
class Row
{
private:
   std::vector<Cell<T> > cells;
};

好吧,这个答案是不正确的。

所以,如果你想存储在一个vector不同的单元格中——你应该使用一些动态类型标识(你可以使用一个基类并将指向它的指针存储在向量中,它只使用虚函数,在所有派生类中都被覆盖,你可以存储类似的内容boost::any并为每个插入的元素保存一些type-identification内容,以便将它们转换为真实类型并使用它)。

于 2013-04-25T09:09:37.050 回答