将子对象转换为父对象
Converting child to parent object
我将使用一个虚拟示例来描述我的问题。假设我们有这样一个架构的程序:
父类:Quadrilateral
子类:Rectangle, Rhombus,…
首先,生成vector<Rectangle>
和vector<Rhombus>
并使用它们的子类属性。后来,我想组合所有四边形,即将两个向量组合成单个vector<quadrilateral>
,因为我不再需要子类属性。将两个向量组合成一个的好处是,我可以将对vector<quadrilateral>
的引用传递到程序的其他部分,在那里它与来自其他类的数据组合在一起。
所以我的问题如下:是否有可能通过只保留Rectangle
的父变量来从Rectangle
中获得Quadrilateral
?或者这是一个非常糟糕的想法,是否有更优雅的方法来实现它?
是的,你绝对可以通过"切片"对象的派生部分来做到这一点。
class Base {};
class Derived : public Base {};
Derived d;
Base b = d; // derived portion is sliced here
然而,在实践中,我从未见过有人故意选择切片他们的对象。我们经常被警告这是c++的一个'gotacha'。
为什么不用指针向量代替呢?
vector<Rectangle*>;
vector<Rhombus*>;
vector<quadrilateral*>;
这样就不会发生切片,如果这些类很大,您可能会从性能提升中获益,因为任何复制vector可能会对指针而不是整个对象进行复制。
是的,你可以这样做。您可以从子对象创建父对象,如下例所示:
struct Base { int base; };
struct Derived : Base { int derived; };
Derived der;
Base base = der;
这个过程被称为slicing
,它在这里工作是因为基类将有默认的复制构造函数,接受对Base的const引用。由于派生类可以自动转换为对基类的const引用,所以一切都很顺利。但我对整体设计不太确定。通常要避免切片。
根据评论中的一些问题,我认为有必要澄清一下。
与它的外观相反,Base base = der;
不调用赋值操作符。相反,它调用复制构造函数——这是变量声明的语义。它相当于Base base(der)
。下面是一个更有趣的例子:
struct A {
A(int ) { };
A() = default;
// A(const A& ) = delete;
};
A a = 5; // Are your eyes fooling you?
不要相信你的眼睛!从来没有调用过操作符=——在A定义中没有偶操作符=。相反,在语义上调用A(int)构造函数来创建临时的A,然后调用复制构造函数来创建A对象。然而,编译器通常会把对复制构造函数的调用优化掉,并且不会创建多余的临时副本。为了确保这种情况,取消标记为delete
的复制构造函数的注释,程序将拒绝编译。
- 在 C++ 中将对象转换为派生类型
- Swig无法将python3的字节对象转换为std::string
- 如何将 Python 对象转换为 Cython 扩展类型的 std::vector 并返回?
- 使用 c++ 将 2d CAD 对象转换为 TIFF 格式
- 将对象转换为指向对象的指针?
- 将使用基类 Ctor创建的对象转换为派生类
- C++中的重载歧义,用于自动将对象转换为"printable"格式
- 无法将类对象转换为函数默认参数中的参考
- 无法将对象转换为初始化中的对象*
- 使用提升序列化将类对象转换为矢量无符号字符<>
- 防止在执行时将两个类中的两个对象转换为 bool:if(a!=b)
- 如何在Cython中将Python对象转换为C++类型
- 重载运算符 -- 无法在赋值中将对象转换为基类型
- Cpp:Cpp中的JSON解析器,提供支持序列化/反序列化功能,将JSON对象转换为用户定义的类
- 如何将 'int *' 类型的 swig 对象转换为 ctypes int*
- 将对象转换为 char,然后"uncasting it back"
- 如何在C++中使用boost库将类对象转换为json字符串
- 在 c++ 中使用重载运算符将父对象转换为子对象
- 字符串流 - 将对象转换为字符串
- 将Mat对象转换为双arr(OpenCV)