C++中的虚拟关键字使用
Virtual keyword use in C++
我知道C++通过虚拟函数实现了运行时多态性,并且虚拟关键字是继承的,但我看不到在派生类中使用虚拟关键字。
例如,在下面的情况下,即使您在派生类中删除了虚拟关键字,ptr->method()调用仍然会转到派生::method。那么这个虚拟关键字在派生类中还有什么作用呢?
#include<iostream>
using namespace std;
class base
{
public:
virtual void method()
{
std::cout << std::endl << "BASE" << std::endl;
}
};
class derived: public base
{
public:
virtual void method()
{
std::cout << std::endl << "DERIVED" << std::endl;
}
};
int main()
{
base* ptr = new derived();
ptr->method();
return 9;
}
如果派生类的方法通过名称和签名与其中一个基类的虚拟方法匹配,并且匹配的方法是虚拟的,则派生类的该方法也将变为虚拟的。因此,从技术上讲,没有必要在派生类中将此类方法标记为"virtual"。然而,在C++11之前,它曾经是一种很好的实践,因为它对阅读代码的人来说是一个很好的提示(很难记住基类的所有虚拟函数)。
从C++11开始,在派生类中有两个额外的关键字用于实现这一点,这有助于可读性和代码健壮性。它们是"超控"answers"最终"。例如,在派生类的方法中放入«override»可以确保基类的相应方法实际上是虚拟的。«final»关键字也起到了同样的作用,而且它可以防止该方法被进一步重写。
我还在博客中写了更多真实世界的理由和代码示例。
希望能有所帮助。祝你好运
什么都没有。只是为了提醒您哪些功能是虚拟的或非虚拟的。
virtual
仅在基类声明中是必需的。它在派生类中是可选的,在这些情况下可能主要用作提醒。
C++11引入override
使事情变得更加明确:它明确地将派生类中的方法标记为基类的virtual
方法的重写。
派生类中的隐式虚拟方法在派生类中是虚拟的,无需显式定义它们为虚拟的。如果你声明,那将是多余的声明。
ptr->method();
当编译器发现上面的语句时
->它将尝试解析上述语句,因为method()函数是虚拟的,编译器将该调用的解析推迟到运行时。
->当您在运行时创建派生类的对象时,现在编译器将知道此方法是派生类的。
这个虚拟关键字在派生类中还有什么作用
考虑这个场景,在派生形式中还有一个派生类Derived2,它有自己的虚拟方法。
class derived2: public derived
{
public:
virtual void method()
{
std::cout << std::endl << "DERIVED2" << std::endl;
}
};
如果你像下面的一样在main中调用方法()
int main()
{
base* ptr = new derived2();
ptr->method(); //derived2 class method() will get called
return 9;
}
如果derived2中的method()默认情况下不是虚拟的,那么您最终将调用method(()的派生版本,从而失去运行时多态性的好处。
因此,c++的作者在这里做得很好,他们使虚拟关键字继承具有层次性。
virtual关键字在drive类中是可选的,因为根据规则,当您用具有虚拟函数的基类驱动类时,以及当您在drive类编译器中重写虚拟函数时,会在函数的同时隐式分配virtual关键字。因此,您不需要显式地分配虚拟关键字。但是这个关键字在多级继承过程中是必需的。
示例:
在您的代码中,我们添加了此代码。
class derived: public base {
public:
virtual void method() { // In this line virtual keyword is optional.
std::cout << std::endl << "DERIVED :: method function" << std::endl;
}
virtual void display() {
std::cout << std::endl << "DERIVED :: display function" << std::endl;
}
};
class deriveChild: public derived {
public:
void method() {
std::cout << std::endl << "DERIVECHILD :: method" << std::endl;
}
void display() {
std::cout << std::endl << "DERIVECHILD:: display" << std::endl;
}
};
在main()中,如果您使用以下代码,它将为您提供不同的输出。
base *ptr = new deriveChild();
ptr->method(); // will compile and execute
ptr->display(); // will generate error because display() is not part of base class.
现在,如果您想使用deriveChild类的display(),请使用以下代码。
derived *ptr = new deriveChild();
ptr->method(); // Compile and Execute
ptr->display(); // Compile and Execute
- C++虚拟关键字和系统更新
- 虚拟关键字的偏差
- 将虚拟函数与最终关键字结合使用
- 为什么此指针值在C 中添加虚拟关键字后更改
- 如果多级继承,如何使用虚拟关键字
- 与C++中的虚拟关键字混淆
- 虚拟关键字的使用与C++中的简单重新定义
- 如何调用孩子的方法:虚拟关键字不起作用
- 'override'关键字只是对被覆盖的虚拟方法的检查吗?
- 为什么人们将虚拟关键字放在std :: exception :: what()的面前
- 默认关键字虚拟析构函数
- 在 C++11 中同时使用虚拟关键字和覆盖关键字是否有任何细微之处
- 如何避免虚拟关键字
- 在没有虚拟关键字的情况下实现虚拟函数
- 虚拟析构函数和delete关键字
- 虚拟继承:如果关键字在某个时候被遗忘,会发生什么
- 为什么虚拟关键字会增加派生类的大小
- 虚拟继承:当只有一个基类具有"虚拟"关键字时,为什么它有效?有没有更好的方法?
- 具有 *派生* 类中的函数的虚拟关键字对性能的影响
- 虚拟关键字似乎被忽略了