0

所以我这样做:

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

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

4

5 回答 5

4

你应该只有一个std::vector<A*>,然后当你想在里面放一个B或时C,你可以这样做:

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

这将比您目前正在做的任何事情都要好得多。

此外,您应该使用std::unique_ptror std::shared_ptr,具体取决于指针的所有权语义。拥有原始指针是禁忌!!

于 2012-08-06T15:42:33.323 回答
3

这是有效的吗?

不,这不对。如果您访问它会发生什么,这是完全未定义的。

还有另一种方法吗?

是的。这取决于你想做什么:

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

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

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

于 2012-08-06T15:48:47.323 回答
1

您可能需要知道的神奇词汇是“协变”和“逆变”。在这里查看一个非常密切相关的问题。

简短的回答:没有简洁、明智的方法来进行您只想使用强制转换进行的转换。您需要将旧向量的内容复制到新向量中。

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

于 2012-08-06T15:52:10.527 回答
1

而不是绕道 via void*,使用 C++11 只需使用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++ 多态性(即虚拟成员函数)。

于 2012-08-06T15:53:21.333 回答
1

在我看来,好像您正在寻找对泛型(模板)类型的协变支持。C++ 根本不支持这一点。它受CLR 和 C#/VB支持,但仅在最新版本中。

尽管如此,为了回应其他人的回应,你很可能找错了人。我的预感是你想要一个指向 A 类型对象的指针向量......并且这种类型应该包括虚拟方法和虚拟析构函数 - 根据需要。如果没有更好地了解您要解决的高级问题,就不可能更具体地了解合适的替代方法 - 这在您的问题中并不明显。

于 2012-08-06T15:51:39.170 回答