如何将派生对象传递给C++;? 我认为我对C++继承有误解。
比如说,我继承了这一经典遗产:如何将派生对象传递给C++;? 我认为我对C++继承有误解。,c++,inheritance,polymorphism,C++,Inheritance,Polymorphism,比如说,我继承了这一经典遗产: class A{ public: virtual void method1() =0; virtual ~A() = default; } class B : public A{ public : void method1(){doSomething();} } class C : public A{ public : void m
class A{
public:
virtual void method1() =0;
virtual ~A() = default;
}
class B : public A{
public :
void method1(){doSomething();}
}
class C : public A{
public :
void method1(){doSomethingElse();}
}
我如何使另一个类Q拥有类型为B或C的对象,而不事先知道它是哪种类型?(我的意思是我们知道它是A型的,仅此而已)
谢谢你的阅读 类必须确切地知道其所有子对象的类型。动态多态性只能通过间接方式实现。因此,虽然不可能包含多态类型的对象,但可以拥有一个。例如:
struct Q {
shared_ptr<A> object; // could point to B or C
}
structq{
共享的\u ptr对象;//可以指向B或C
}
由于您不想Q
了解B
和C
,因此必须通过指针间接存储A
,因为您无法知道B
、C
或未知的派生类D
需要多少存储空间。对于由Q动态分配和拥有的单个对象,经典的解决方案是a
由于默认情况下,std::unique_ptr
使用delete
删除对象,因此还需要一个虚拟析构函数
#include"A.hpp"
#include<memory>
class Q {
std::unique_ptr<A> a;
public:
Q(std::unique_ptr<A> ai) : a{std::move(ai)} {}
};
#包括“A.hpp”
#包括
Q类{
std::唯一的ptr a;
公众:
Q(std::unique_ptr ai):a{std::move(ai)}{
};
如果您不想独占Q对A的所有权,或者不想提供虚拟析构函数,也可以使用std::shared_ptr
。共享指针动态地记住存储的类,因此如果它们被正确地创建,就可以正确地销毁对象,特别是使用std::make_Shared
。此外,它们还使用引用计数,只有在对象的所有引用都消失后才会删除该对象。
缺点是,与std::unique\u ptr相比,std::unique\u ptr通常没有普通指针的开销。容器必须包含指向基类型的指针,才能提供多态功能。例如一个std::unique\u ptr
。在类Q
中,你应该有一个指向a
的智能指针,不要忘记。你的代码仍然无效,除非foo
是void
的别名,我认为警告是因为缺少return
语句。可能需要谨慎地指出std::unique\u ptr
具有未定义的行为,除非将~A
修改为虚拟。@user2079303:谢谢,这是正确的,我编辑了答案。附加说明,可能有点离题:通过声明虚拟析构函数,隐式移动构造函数/赋值将被抑制,并且复制操作将用于移动。如果A
、B
或C
包含复制速度慢但移动速度快的成员,则这是非常不可取的。由于C++11,一个很好的经验法则是每当声明析构函数时总是声明默认的移动操作。@user207933当计划以多态方式使用B和C的对象并通过智能指针动态管理这些对象时,唯一明智的做法是禁用这些类的移动和复制,以及使用这些类的移动和复制相反,指针。@ÖTiib禁用类的移动将是愚蠢的。有效地实现这一点很简单,而且非常有用。复制将通过具有唯一指针成员而自动禁用,我同意无需特意实现它。共享ptr不是为拥有而设计的,而是为共享所有权而设计的。大量使用is作为拥有智能指针是一种初步的悲观情绪,这使得许多代码毫无意义地低效。@ÖöTiib不是真的。共享指针实际上是为拥有而设计的。更具体地说是共享的。当然,这可能会有点慢,这取决于用例,但这也是拥有一个缺少虚拟析构函数的多态对象的最简单的方法。在不需要共享所有权的情况下使用shared_ptr只是令人困惑。将虚拟析构函数始终添加到多态类。现代编译器尽可能避免通过vtable调用它。它只是使层次结构更加可靠。进一步的分析表明,Q需要的不是一个A,而是A的集合。所以程序员接受boost::ptr_向量,但忘记检查A的析构函数是虚拟的,并且具有未定义的行为。