"virtual"关键字在C++的基类中是可选的吗?
Is the "virtual" keyword optional in base classes in C++?
我试图理解c++中"virtual"关键字的功能-考虑这个例子:
#ifdef USE_VIRTUAL
struct a {
virtual void say_hi() { std::cout << "hello from a" << std::endl; }
};
#else
struct a {
void say_hi() { std::cout << "hello from a" << std::endl; }
};
#endif
struct b : public a {
void say_hi() { std::cout << "hello from b" << std::endl; }
};
int main( int argc, char** argc )
{
a a_obj;
b b_obj;
a_obj.say_hi();
b_obj.say_hi();
}
程序输出:
hello from a
hello from b
,不管a::say_hi是否声明为virtual。因为即使没有将say_hi声明为虚函数,函数也会被正确重写,那么将其声明为虚函数的功能是什么?
您没有使用多态性。多态行为只影响指向基类的指针和引用,如下所示:
class A; class B1 : A; class B2 : A;
B1 x;
B2 y;
A z;
A & a1 = x; // static type A&, dynamic type B1&
A & a2 = y; // static type A&, dynamic type B2&
A & a3 = z; // static and dynamic type A&
现在访问a1
, a2
, a3
的成员函数受多态性和虚调度的约束。
然而,你必须声明第一个函数在继承层次结构的顶部是虚的,即在A
!在您的示例中,没有virtual
,就没有多态性,您总是调用对象的相应静态类型的成员函数。要测试这一点,再添加几行:
a & bref = b_obj;
bref.say_hi(); // call b::say_hi() if virtual, a::say_hi if not
bref.a::say_hi(); // always call a::say_hi()
相关文章:
- std::具有相同基类的类的变体
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 基类中的函数名称解析
- C++初始化基类
- 如何通过派生类函数更改基类中的向量
- 如何定义一个纯抽象基类
- 如何使用基类指针引用派生类成员
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 在基类中调用的 VIrtual 基函数,C++
- 为什么必须将"virtual"放入基类中,而不是仅在子类中使用"override"?在C++
- 有没有办法在C++基类中创建一个"virtual"变量?
- 关键字是否"virtual"传递给中间基类?
- 通过在基类中声明 virtual 对派生类所做的更改
- 派生类使用或不带 "virtual" 前缀重写基类的虚函数之间有什么区别?
- "virtual"关键字在C++的基类中是可选的吗?
- 什么是从虚拟基类继承的虚函数的"virtual thunk"?
- C++:当方法在基类中不是虚拟时,在派生类中声明该方法 virtual 是否合法?