C++ V 形转换:vector<Base1*> 到 vector<Base2*>
C++ V-shape casting: vector<Base1*> to vector<Base2*>
我很难弄清楚这个转换问题。以 3 类:
开头
#include <vector>
// Pure virtual class
class Base1{
public:
virtual ~Base1();
virtual void do_sth()=0;
}
class Base2{
public:
int prop=3;
~Base2();
}
class Derived: public Base1, Base2{
~Derived();
void do_sth(){print("Hi");};
}
如何执行以下转换?
std::vector<Base1*> vec1
vec1.reserve(10);
for( int i = 0; i < 10; ++i )
vec1.push_back(new Derived());
// To this type...?
std::vector<Base2*> vec2 = ?????;
一些备注:
- 我会使用
dynamic_cast
执行从 Base1 到 Derived 的安全转换。
- 理想情况下,在此过程中不创建任何对象副本!。
- 到目前为止我最好的选择是调用
vec2.data()
来获得一个 Base1*
指针,然后 dynamic_cast 到 Derived,然后静态转换为 Base2,但我不知道如何转移内存所有权以及如何传递向量大小。
vec1
和 vec2
中都没有 Derived
对象,因此您无法从其中任何一个的元素获取指向 Derived
的其他基础子对象的指针.
如果将 Derived
传递给 vec1.push_back
,它将从 Derived
的 Base1
子对象复制构造一个 Base1
。这称为对象切片。
如果在 vec1
中有指向 Base1
的 指针 (原始或智能)向量,那么它们可能指向 Base1
Derived
的基础子对象,此时你可以 dynamic_cast<Base2*>
它们,这通常会给你一个不同的指针值。
问题的评论变得相当混乱,所以我将 post 在此部分回答,而不是试图理清评论。
Base1
有虚函数。好的开始。
Derived
派生自 Base1
.
Derived
也派生自 Base2
.
如果您有一个 Derived
类型的对象,您可以创建一个指向 Base1
的指针,该指针指向派生对象:
Derived d;
Base1* b1 = &d;
现在你有一个指向多态基的指针class,你可以使用dynamic_cast
来执行交叉转换:
Base2* b2 = dynamic_cast<Base2*>(b1);
编译器知道如何做到这一点,结果应该与您直接获得的指针值相同:
Base2* b2x = &d;
assert(b2x == b2);
还请注意,由于代码在指针向量中传输,因此 Derived
对象似乎是使用 new Derived
创建的。如果是这样,并且最终代码通过指向其中一种基类型的指针删除了 Derived
对象,那么基类型 必须 具有虚拟析构函数。
我很难弄清楚这个转换问题。以 3 类:
开头#include <vector>
// Pure virtual class
class Base1{
public:
virtual ~Base1();
virtual void do_sth()=0;
}
class Base2{
public:
int prop=3;
~Base2();
}
class Derived: public Base1, Base2{
~Derived();
void do_sth(){print("Hi");};
}
如何执行以下转换?
std::vector<Base1*> vec1
vec1.reserve(10);
for( int i = 0; i < 10; ++i )
vec1.push_back(new Derived());
// To this type...?
std::vector<Base2*> vec2 = ?????;
一些备注:
- 我会使用
dynamic_cast
执行从 Base1 到 Derived 的安全转换。 - 理想情况下,在此过程中不创建任何对象副本!。
- 到目前为止我最好的选择是调用
vec2.data()
来获得一个Base1*
指针,然后 dynamic_cast 到 Derived,然后静态转换为 Base2,但我不知道如何转移内存所有权以及如何传递向量大小。
vec1
和 vec2
中都没有 Derived
对象,因此您无法从其中任何一个的元素获取指向 Derived
的其他基础子对象的指针.
如果将 Derived
传递给 vec1.push_back
,它将从 Derived
的 Base1
子对象复制构造一个 Base1
。这称为对象切片。
如果在 vec1
中有指向 Base1
的 指针 (原始或智能)向量,那么它们可能指向 Base1
Derived
的基础子对象,此时你可以 dynamic_cast<Base2*>
它们,这通常会给你一个不同的指针值。
问题的评论变得相当混乱,所以我将 post 在此部分回答,而不是试图理清评论。
Base1
有虚函数。好的开始。
Derived
派生自 Base1
.
Derived
也派生自 Base2
.
如果您有一个 Derived
类型的对象,您可以创建一个指向 Base1
的指针,该指针指向派生对象:
Derived d;
Base1* b1 = &d;
现在你有一个指向多态基的指针class,你可以使用dynamic_cast
来执行交叉转换:
Base2* b2 = dynamic_cast<Base2*>(b1);
编译器知道如何做到这一点,结果应该与您直接获得的指针值相同:
Base2* b2x = &d;
assert(b2x == b2);
还请注意,由于代码在指针向量中传输,因此 Derived
对象似乎是使用 new Derived
创建的。如果是这样,并且最终代码通过指向其中一种基类型的指针删除了 Derived
对象,那么基类型 必须 具有虚拟析构函数。