2013-04-25 92 views
8

的矢量我有一个名为细胞模板类,如下所示: -C++:模板类

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

现在我想另一个类命名的行。行将有一个名为Cells的向量,这样我可以将Cell和Cell类型的元素都添加到该向量中。可能吗?

如果是这样,我该怎么做? 在此先感谢。

+0

你是否想要一个行保存,例如,一个单元格,单元格和任何其他单元格类型在一个向量<>? – Skizz 2013-04-25 09:14:00

+0

是的你是对的。我完全想要那样。 – 2013-04-25 09:18:27

+0

是否意味着你想要多态容器?你只能使用动态多态(继承)而不能使用静态多态(模板)。 – Elazar 2013-04-25 09:21:13

回答

12

与您提供的额外的细节,前两个答案,将无法正常工作。你需要的是一种被称为单元变体的类型,然后你可以拥有这些类型的矢量。例如: -

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>存储了单元格,则由于object slicing,您将丢失数据。

+0

+1。联合不仅仅是痛苦,它也不是类型安全的,这是模板的全部目的。 – Elazar 2013-04-25 09:30:45

+0

非常感谢。我将使用第二种方法。感谢所有人试图帮助我。 – 2013-04-25 09:36:38

+0

还有一件事,请提供示例代码来添加元素并使用迭代器访问元素?提前致谢。 – 2013-04-25 10:01:07

6

像这样的东西?

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

好的,这个回答是错误的。因此,如果你想在一个vector中存储不同的单元格 - 你应该使用一些动态类型标识(你可以使用一个基类并在向量中存储指向它的指针,该指针只使用虚函数,它被覆盖所有派生类,您可以存储类似boost::any的东西,并为每个插入的元素保存一些type-identification,以将它们转换为实际类型并使用它)。

+0

Jakir - 注意最后一个'>'之前的空格,以避免与'>>'操作符混淆。虽然C++ 11不需要这个。 – Elazar 2013-04-25 09:11:35

+0

它可能无法正常工作。因为当创建Row类型对象时,我必须提供类型参数。矢量将是这种类型。 – 2013-04-25 09:12:49

+0

@JakirHossain然后你可以添加一个模板参数。并将其用于行特定的事物,并将T用于单元格。 – stardust 2013-04-25 09:16:12

5

对方回答是好的,但你可能想:

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

    std::vector<Cell> cells; 
    ... 
} 
5

这是不可能的原因在C++中,但在Java/Python中可能是因为:在C++向量中,STL容器的存储(由vector :: data()返回)包含所有对象实例化包装。其中每个元素必须具有相同的大小。这使得寻址快速和方便。因此,假设你定义了一个模板类A,其大小将取决于模板变量“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的相同功能。

+0

你的程序显示错误'cpp:25:13:error:'shared_ptr'没有在这个范围内声明' – 2016-04-17 05:35:56

+0

@PraveenVinny那是因为你没有用-std编译= C++ 11。对于C++ 11,shared_ptr仅在中。 – xuancong84 2016-06-06 07:39:31