2

考虑这个简单的代码:

class A {
};

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

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

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

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

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

拜托,不需要谈论我正在使用的提升或语法等......我真的只是想了解这个概念......我还不清楚。我对此有一些答案,但我想它们涉及太多演员来检查东西,我来这里是为了知道是否有更好的答案......

谢谢!
乔纳森

ps:你们能回答我的评论吗?有时我在这里问一些东西,然后最好的回答者来了,然后就不回来了:(。或者我应该问另一个问题而不是评论提问?

4

4 回答 4

3

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

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
}
于 2009-11-03T18:27:26.747 回答
2

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

于 2009-11-03T18:23:24.237 回答
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
于 2009-11-03T18:45:02.150 回答
0

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

撇开您不应该从 STL 容器继承(由于一些可能不明显的原因),答案是您不应该继承。反正也不是。

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

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

但这依赖于 C++ 的 RTTI 支持,这通常非常慢。您可以改为使用某种“自己滚动”的 RTTI 接口(,返回标识类的枚举的函数),或者可能使用 Boost 的静态断言来测试typeof对象。

我的偏好是这样的:

template<typename T>
class V1 {
private:
    std::vector<T*> _vec;
// ...
};

T然后使用对您的用例有意义的类型进行实例化。

但是,如果您的案例依赖于有时是 all B*s 有时是 all A*s,那么我会认为您的设计很糟糕,应该重新考虑。

于 2009-11-03T19:24:44.573 回答