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

发布于 2024-08-09 19:00:40 字数 615 浏览 6 评论 0原文

考虑这个简单的代码:

class A {
};

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

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

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

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

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

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

谢谢!
乔纳森

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

Consider this simple code:

class A {
};

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

if I have a instance of V1, then any object derived from A can be inserted into the vector, ok here.

Now, lets say I have two simple classes called B and C both derives from A;
if I have a instance of V1, then both pointers of B and C can be inserted into this vector, I guess this is right to afirm?

if so, how can I derive a vector from V1 to make sure only B pointers are inserted?
I was thinking about using templates, but in this case I already know the base of the class and in tempaltes you can use anything, right?

Don't know if I am being clear, my english doesn't help...
Would I have to override push_back and other functions to check if the template argument is derived from A?

Please, don't need to talk about boost or syntaxes I am using etc... I really just want to understand the concept of this... it is not clear in my mind yet. I have some answers to this but I guess they involve too much of casts to check stuff and I came here to know if there is a better answer to it...

Thanks!
Jonathan

ps: Can you guys please answer comments I put? sometimes I ask stuff here and then the best answerers come and don't come back :(. Or should I just ask another question instead of comment questioning?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忆悲凉 2024-08-16 19:00:40

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

class A {
};

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

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

是的,正确。

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

是的,正确。

如果是这样,我怎样才能从中导出向量
V1 确保只有 B 指针
插入?我正在考虑使用
模板,但在这种情况下我已经
了解班级的基础和
您可以使用任何模板,对吗?

不使用 a 呢

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

也许你有充分的理由从向量继承,但我现在没有看到它......如果你需要添加功能,最好让 V1 包装 std::vector,即:

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

It's not clear from your example if inheritance is needed. You may also not realize it is dangerous, because std::vector does not have a virtual destructor. That means V1's destructor will not be called upon deletion of a pointer to the base class and you may end up leaking memory/resources. See here for more info.

class A {
};

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

if I have a instance of V1, then any object derived from A can be
inserted into the vector, ok here.

Yes, correct.

Now, lets say I have two simple
classes called B and C both derives
from A; if I have a instance of V1,
then both pointers of B and C can be
inserted into this vector, I guess
this is right to afirm?

Yes, correct.

if so, how can I derive a vector from
V1 to make sure only B pointers are
inserted? I was thinking about using
templates, but in this case I already
know the base of the class and in
tempaltes you can use anything, right?

Why not use a

std::vector<B*> m_bVector;

for this case? Here's how it would work:

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

Maybe you have a good reason for inheriting from vector, but I don't see it right now... If you need added functionality, it may be better to have V1 wrap the std::vector, ie:

class V1
{
private:
   std::vector<A*> m_aVec;
public:
   // use AVec
}
黑凤梨 2024-08-16 19:00:40

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

As a general rule of thumb, you shouldn't derive from STL containers. Why not use a vector<A*> member inside of class V1?

不即不离 2024-08-16 19:00:40

如果您想在向量中存储 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

If you want to store B-pointers in your vector, the best solution is to derive from

std::vector<B*>

Or if you want to have possibility to use your class also with A-pointers, make a template

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

MyVec<A*> va; // stores A* and B*
MyVec<B*> vb; // stores B* only
迷你仙 2024-08-16 19:00:40

如果是这样,我如何从 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 类型进行实例化。

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

if so, how can I derive a vector from V1 to make sure only B pointers are inserted?

Setting aside that you shouldn't inherit from the STL container (for a number of reasons that may not be obvious), the answer is that you don't. Not really, anyway.

You can make a run-time assertion that only B* can be inserted:

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

But this relies on C++'s RTTI support, which is typically very slow. You could instead use some kind of "roll-your-own" RTTI interface (i.e., a function that returns an enum identifying the class), or perhaps Boost's static assert testing the typeof the object.

My preference would be this:

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

And then instantiate with a type for T that makes sense for your use case.

But if you have a case that relies on sometimes there being all B*s and sometimes all A*s, then I would submit that your design stinks and should be rethought.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文