强制派生的类对象使用自己的功能,而不是基类功能
Force a derived-class object to use its own function, not the base-class one
我对C 中的子类有一些疑问。我有此代码:
class BaseClass() {
BaseClass();
void doSomething();
}
class SubClass : public BaseClass {
SubClass();
void doSomething();
}
当我声明一个可能是子类的基本对象时,我会调用子构造函数...
BaseClass foo = SubClass();
然后我需要foo来使用派生类的dosomething()方法,但是当我这样做时...
foo.doSomething();
它使用父类方法而不是派生的方法。我尝试了这个,但它不起作用:
foo.SubClass::doSomething();
有什么方法可以做到这一点,或者我被迫用"子类"类型声明对象,以使其使用自己的函数?
问题1:对象切片
在您的初始化中
BaseClass foo = SubClass();
您创建一个匿名临时SubClass
对象并复制构造BaseClass
对象。这意味着Foo是并且仍然是从SubClass
复制的BaseClass
。
这称为对象切片。如果baseClass
将具有数据成员,则将复制该子类的相应数据成员。如果SubClass
将有其他数据成员,则将丢失。
如果您想使用BaseClass
对象,但是在不失去其实际类型的成员的情况下,无论是基础还是派生,则需要使用参考或指示:
BaseClass *foo = new SubClass; // foo is a base class pointer but points to a SubClass object.
SubClass bar;
BaseClass& foo2 = bar; // foo2 is a base class REFERENCE which refers to a Subclass object
但是,这还不够。
问题2:多态性
如果您现在调用该方法:
foo->doSomething();
foo2.doSomething();
尽管对象的真实类型指向/引用了对象的实际类型,但仍将被称为BaseClass::doSomething()
。这是因为对于正常的成员函数,编译器试图在编译时识别要调用的功能:在编译时,它只知道指针或参考的类型。
要从多态行为中受益,您还需要将功能定义为Johan所解释的virtual
。在这种情况下,编译器将生成代码,其中有些开销能够动态识别对象的类型,因此可以完全按照您的预期调用函数的正确版本。
请注意,如果您的基类中至少具有一个虚拟功能,则最好为其声明虚拟驱动器。
使用虚拟和覆盖:
class BaseClass() {
BaseClass();
virtual ~BaseClass() = default;
virtual void doSomething();
}
class SubClass : public BaseClass {
SubClass();
void doSomething() override ;
}
编辑:正如克里斯托夫所说的那样,使用上述虚拟破坏者。
您可以在
中声明dosomeThing
方法虚拟 virtual void doSomething()
{
----
}
相关文章:
- std::具有相同基类的类的变体
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 基类中的函数名称解析
- 扩展基类并在不更改派生类的情况下使用该功能
- 具有相同纯虚拟功能的两个基类
- 基类的通用成员功能数组
- 朋友功能是否继承?为什么基类朋友功能在派生的类对象上工作
- 在基类中公开使用功能,并在派生类中私下使用
- 继承:从基类调用派生的类功能
- C 从基类调用派生类功能
- 强制派生的类对象使用自己的功能,而不是基类功能
- 用于抽象基类和派生类的工厂功能的C 返回类型
- 如何使用Gmock检查基类功能
- 在基类崩溃中调用虚拟功能
- C 在功能参数中指向基类指针的指针
- 使用基类功能模板专业化
- 与基类不同的返回类型的C 覆盖功能
- 虚拟基类是否是可行和/或有用的功能
- Qt:如何为所有小部件和小部件类型实现通用基类信号/插槽功能(通过虚拟基类插槽)