为什么不能在构造函数中使用虚函数
2017-11-21 22:00
337 查看
先上代码:
此时发挥作用的是Base:fun()而不是派生类A:fun(),也就是虚函数在构造函数中不起作用。当实例化一个派生类对象时,首先进行基类部分的构造,然后再进行派生类部分的构造。即创建A对象时,会先调用Base的构造函数,再调用A的构造函数。当在构造基类部分时,派生类还没被完全创建,从某种意义上讲此时它只是个基类对象。即当Base::fun()执行时A对象还没被完全创建,此时它被当成一个Base对象,而不是A对象,因此fun绑定的是Base的fun
C++之所以这样设计是为了减少错误和Bug的出现。假设在构造函数中虚函数仍然“生效”,即Base::fun()中的fun();所调用的是A::fun()。当Base::fun()被调用时派生类中的数据a还未被正确初始化,这时执行A::fun()将导致程序对一个未初始化的地址解引用,得到的结果是不可预料的,甚至是程序崩溃(访问非法内存)。
// c_datastructure.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<iostream> #include<string> using namespace std; class Base { public: Base() { fun(); } virtual void fun() { cout << "Base" << endl; } }; class A :public Base { public: A() :Base(), a(a) {} virtual void fun() { cout << "A" << endl; } private: int a; }; int main() { cout << "************" << endl; Base *a = new A; delete a; return 0; }
此时发挥作用的是Base:fun()而不是派生类A:fun(),也就是虚函数在构造函数中不起作用。当实例化一个派生类对象时,首先进行基类部分的构造,然后再进行派生类部分的构造。即创建A对象时,会先调用Base的构造函数,再调用A的构造函数。当在构造基类部分时,派生类还没被完全创建,从某种意义上讲此时它只是个基类对象。即当Base::fun()执行时A对象还没被完全创建,此时它被当成一个Base对象,而不是A对象,因此fun绑定的是Base的fun
C++之所以这样设计是为了减少错误和Bug的出现。假设在构造函数中虚函数仍然“生效”,即Base::fun()中的fun();所调用的是A::fun()。当Base::fun()被调用时派生类中的数据a还未被正确初始化,这时执行A::fun()将导致程序对一个未初始化的地址解引用,得到的结果是不可预料的,甚至是程序崩溃(访问非法内存)。
相关文章推荐
- 为什么构造函数不能是虚函数
- 为什么构造函数不能为虚函数
- 构造函数为什么不能是虚函数
- 为什么构造函数不能是虚函数而析构函数可以
- 构造函数为什么不能是虚函数
- 构造函数为什么不能是虚函数
- 为什么构造函数不能为虚函数
- 为什么构造函数不能声明为虚函数,析构函数可以
- 为什么对于类的const成员,只能使用初始化列表,而不能在构造函数内部进行赋值操作
- 为什么构造函数不能为虚函数,而析构函数可以为虚函数
- C++里的构造函数为什么不能为虚函数
- 构造函数为什么不能是虚函数
- c++的构造函数为什么不能是虚函数,而基类的析构函数必须是虚函数?
- 构造函数为什么不能是虚函数
- 构造函数为什么不能是虚函数 ( 转载自C/C++程序员之家)
- 为什么构造函数不能虚而析构函数可以虚,以及在什么情况下来使用析构函数
- 构造函数为什么不能是虚函数
- 为什么构造函数不能声明为虚函数,析构函数可以
- 构造函数为什么不能是虚函数 ( 转载自C/C++程序员之家)
- C++构造函数为什么不能是虚函数