繁体   English   中英

使用* void作为static_cast的缓冲区

[英]using *void as a buffer for static_cast

所以我去这个:

class A;

class B : public A;

class C : public B;

vector<A*> *vecA;

vector<C*> *vecC;

我想将vectC转换为vecA。

vector<A*> *_newA = static_cast< vector<A*>* >(vecC); //gives an error

因此,我将void指针用作缓冲区和演员表:

void *buffer = vecC;

vector<A*> *_newA = static_cast< vector<A*>* >(buffer); //works

这有效吗? 还有另一种方法吗?

您应该只具有一个std::vector<A*> ,然后当您希望在其中放入BC ,可以这样做:

 std::vector<A*> vec;
 vec.push_back(b);

这将比您目前正在执行的任何操作都要好得多。

另外,根据指针的所有权语义,应使用std::unique_ptrstd::shared_ptr 拥有原始指针是不行的!!

这有效吗?

不,这不对。 完全不确定,如果您访问它会发生什么。

还有另一种方法吗?

是。 这取决于您想做什么:

  1. 复制内容: std::copy(vecC.begin(), vecC.end(), std::back_inserter(vecA));

  2. 如果给定C*的容器或迭代器或任何其他派生类型,则创建一个充当A*随机访问容器的适配器

  3. 我确定还有其他解决方案,只需告诉我们您想做什么

在我看来,您似乎正在寻找对通用(模板)类型的协变支持。 C ++完全不支持此功能。 CLR和C#/ VB支持它,尽管仅在最新版本中支持。

尽管如此,要呼应他人的回应,您可能会吠叫错误的树。 我的直觉是,您希望有一个指向A型对象的指针的向量……并且这种类型应包括虚方法和虚析构函数-必要时。 如果没有更好地了解您要解决的高级问题,就不可能更具体地讨论合适的替代方法,这在您的问题中并不明显。

您可能需要知道的魔术词是“协方差”和“逆方差”。 在这里查看一个非常相关的问题。

简短的答案:没有一种整洁,明智的方法可以仅通过强制转换来进行您想要的转换。 您将需要很长一段时间才能将新载体复制到旧载体的内容中。

但更重要的是:1.永远不要在标准容器类型上使用new 2.不要传递指向标准容器类型的指针。 3.不要将原始指针传递给自己的对象,而应使用std::shared_ptr

在C ++ 11中,不要通过void*绕行,而只需使用reinterpret_cast

但是,您想要的转换允许非常不好的事情

#include <iostream>
#include <vector>
using namespace std;

class Base {};

class Derived: public Base
{ public: int x; Derived(): x(42) {} };

int main()
{
    vector< Derived* >  v;
    Derived             d;

    v.push_back( &d );
    cout << v.back()->x << endl;        // 42

    vector< Base* >*    pbv =
        reinterpret_cast< vector< Base* >* >( &v );
    Base                b;

    pbv->push_back( &b );
    cout << v.back()->x << endl;        // indeterminate value
}

与将T**转换为T const**大致相同(不允许,可能会带来不好的事情)。 简而言之,除非您确切知道自己在做什么,否则不要这样做。 它的时间较长,嗯,这里没有讨论的余地,但是它涉及区分可变和不可变的集合,并且要非常小心。


编辑:正如其他人(未解决转换问题)已经指出的那样,一个实际的解决方案是A指针或智能指针的向量,然后使用C ++多态性(即虚拟成员函数)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM