C++ 多态性与常规继承?

C++ 多态性与常规继承?,c++,inheritance,polymorphism,virtual-functions,C++,Inheritance,Polymorphism,Virtual Functions,我经常使用多态性,但我突然意识到了这一点。我的代码是: class A{ class B : public A{ class C : public A{ 我使用classA作为多态参数类型,用于传入B或C子类型: //Accepts B and C objects void aMethod(A* a){ 然而,我给了A一个虚拟析构函数-这是A(以及B和C)包含vtable指针的唯一原因 所以我的问题是,如果我没有用虚拟析构函数声明A,那么A就不会是多态的-我就不能在aMethod()?”

我经常使用多态性,但我突然意识到了这一点。我的代码是:

class A{

class B : public A{

class C : public A{
我使用class
A
作为多态参数类型,用于传入
B
C
子类型:

//Accepts B and C objects
void aMethod(A* a){
然而,我给了
A
一个虚拟析构函数-这是A(以及B和C)包含vtable指针的唯一原因

所以我的问题是,如果我没有用虚拟析构函数声明A,那么A就不会是多态的-我就不能在
aMethod()
?”中传递类型为B或C的对象


因此,非多态性继承只是为了共享代码,而多态性(基类必须有一个vtable)允许将子类型作为基类类型的参数传递?

在您提供的代码中

void aMethod(A a){
a
形式参数不是多态的。它是按值传递的。当您传入一个
B
C
对象作为实际参数时,您只是将它切分为
a
,也就是说,您只是复制
a
基类子对象


关于

那么,非多态性继承仅仅是为了共享代码,而多态性(基类必须有一个vtable)允许将子类型作为基类类型的参数传递

它结合了两个必须分开处理的问题

从非多态类继承是关于代码共享的,是的,但它也引入了is-a关系,这对于例如通过引用传递很重要


从多态类(具有一个或多个虚拟成员函数的类)继承允许您重写基类功能,或者在基类将其作为派生类职责的情况下实现基类功能–通常通过使用纯虚拟成员函数。这意味着基类中的成员函数可以调用派生类的成员函数。另外,通过基类指针或引用调用成员函数,可以调用派生类的实现。

非多态类型还包含每个基类的子对象,并且向上转换仍然是隐式的


因此,即使没有多态性,也可以很好地传递派生类的对象。接收器将作用于基本子对象,就像多态类型的数据成员和非虚拟函数一样。

一个类及其析构函数唯一的
虚拟
方法,就像您的
类A
,是一个奇怪的东西。这样的类在设计良好的代码中是没有必要的


从您的问题来看,不清楚是否需要
虚拟
析构函数(即,如果您曾经通过类
a
的引用或指针调用类
B
C
的析构函数),但如果需要,您的代码会发出异味。如果不是,则只需将析构函数设置为非虚拟。

void-aMethod
获取类型为
A
的对象?您需要它为多态性引入一个指针或引用。否则,您只是在切片
B
C
对象。如果您的参数按示例中的值传递,则对象将被切片。这在10年前可能是个好问题,A)还有其他更好的方法来实现多态行为B)你的标题没有反映问题C)继承是关于关系/财产的,不管你怎么称呼它,
virtual
关键字本身并没有改变这一点,它只添加了多态性方面的内容。好的,但我所描述的内容不需要任何重写。我有一个普通的继承层次结构,其中基类有一个虚拟析构函数。。。。。如果我删除虚拟dtor-它的正常继承。这是否意味着aMethod()将不再工作?@user997112:关于
aMethod
,您可以将析构函数设置为非虚拟,或者如果它不起任何作用,则将其完全删除。但这并不能帮你省很多钱,真的。它有一种过早优化的味道。优化的一般建议是测量,以发现您是否真的需要它。继承需要一个虚拟析构函数,否则对象将在销毁中被切片(例如,如果您调用
C*C=new C();A*A=C;delete A
,将调用析构函数,而不是C)。@Leonardo我知道(如果你仔细阅读了我的答案,你就不会知道了)。但是像这样一个没有任何其他
virtual
方法的类几乎没有任何用处。