需要一个从向量派生的向量

时间:2009-11-03 18:20:41

标签: c++ inheritance templates vector specialization

考虑这个简单的代码:

class A {
};

class V1: vector<A *>{
  // my nice functions
};

如果我有V1的实例,那么从A派生的任何对象都可以插入到向量中,好了。

现在,假设我有两个名为B和C的简单类,它们都来自A;
如果我有V1的实例,那么B和C的两个指针都可以插入到这个向量中,我想这是正确的吗?

如果是这样,我如何从V1导出一个向量以确保只插入B指针? 我正在考虑使用模板,但在这种情况下,我已经知道了类的基础,并且在tempaltes中你可以使用任何东西,对吗?

不知道我是否清楚,我的英语没有帮助...
我是否必须覆盖push_back和其他函数来检查模板参数是否派生自A?

请不要谈论我正在使用的提升或语法等等......我真的只是想理解这个概念......我脑海里还不清楚。我有一些答案,但我猜他们涉及太多的演员来检查东西,我来到这里知道是否有更好的答案......

谢谢!
乔纳森

ps:你能回答我的评论吗?有时候我会问这里的东西然后最好的回答者来不回来:(或者我应该问另一个问题而不是评论问题?

4 个答案:

答案 0 :(得分:3)

从您的示例中不清楚是否需要继承。您可能也没有意识到它是危险的,因为std :: vector没有虚拟析构函数。这意味着在删除指向基类的指针时不会调用V1的析构函数,最终可能会泄漏内存/资源。有关详细信息,请参阅here

class A {
};

class V1: vector<A *>{
  // my nice functions
};
  

如果我有V1的实例,那么从A派生的任何对象都可以   插入到矢量中,好吧。

是的,没错。

  

现在,让我说我有两个简单的   称为B和C的类都是派生的   来自A;如果我有一个V1的实例,   那么B和C的两个指针都可以   插入到这个向量中,我想   这是对的吗?

是的,没错。

  

如果是这样,我如何从中导出一个向量   V1确保只有B指针   插入?我正在考虑使用   模板,但在这种情况下我已经   知道班级的基础和   你可以使用任何东西,对吗?

为什么不使用

std::vector<B*> m_bVector;

对于这种情况?以下是它的工作原理:

B* bInstance = new B();
A* aInstance = new A();
m_bVector.push_back(bInstance);
m_bVector.push_back(aInstance); //< compiler error

也许你有充分的理由从vector继承,但我现在没有看到它......如果你需要增加功能,那么让V1包装std :: vector可能会更好,即:

class V1
{
private:
   std::vector<A*> m_aVec;
public:
   // use AVec
}

答案 1 :(得分:2)

作为一般经验法则,您不应该从STL容器派生。为什么不在vector<A*>内使用class V1成员?

答案 2 :(得分:1)

如果要在向量中存储B指针,最好的解决方案是从

派生
std::vector<B*>

或者,如果你想让你的班级也使用A指针,可以制作一个模板

template<typename T>
class MyVec : public std::vector<T> {
};

MyVec<A*> va; // stores A* and B*
MyVec<B*> vb; // stores B* only

答案 3 :(得分:0)

  

如果是这样,我如何从V1导出一个向量以确保只插入B指针?

撇开你不应该从STL容器继承(对于可能不明显的number of reasons),答案是你没有。不管怎样,不是真的。

您可以进行只能插入B*的运行时断言:

if(!dynamic_cast<B*>(item))
    return false;

但这依赖于C ++的RTTI支持,通常非常慢。您可以使用某种“自己动手”的RTTI接口(,一个返回标识该类的枚举的函数),或者可能是Boost的static assert测试{{1对象。

我的偏好是:

typeof

然后使用template<typename T> class V1 { private: std::vector<T*> _vec; // ... }; 的类型进行实例化,这对您的用例有意义。

但是如果你的案例有时会依赖于所有T,有时候所有B*,那么我会认为你的设计很糟糕,应该重新思考。