C++进阶--构造函数和析构函数中的虚函数

//############################################################################
/*
任何时候都不要在构造函数或析构函数中调用虚函数
*/
class dog {
    public:
        string m_name;
        dog(string name) {m_name = name;  bark();}
        virtual void bark() { cout<< "Woof, I am just a dog " << m_name << endl;}
};

class yellowdog : public dog {
    public:
        yellowdog(string name) : dog(string name) {...}
        virtual void bark() { cout << "Woof, I am a yellow dog " << m_name << endl; }
};

int main ()
{
  yellowdog mydog("Bob");
}

输出:
Woof, I am just a dog Bob.

/*
在构造的过程中,所有虚函数表现为非虚函数

为什么?
基类在派生类之前构造。
所以bark()的时候,yellowdog还没有构造

为什么Java中表现不一样?

Java和C++在定义对象的生命周期上有一个基本的差异
Java: 所有成员在构造函数运行前被null初始化。生命周期在构造函数之前已经开始
C++: 构造函数负责初始化成员。生命周期在构造函数结束之后才开始

调用对象中还未被初始化的部分是继承危险的
调用对象中已经被delete的部分也是危险的
*/

/*
解决方法 1:
不使用多态,使用初始化参数来产生运行时差异
*/
class dog {
    public:
        ...
        dog(string name, string color) {m_name = name; bark(color);}
        void bark(string str) { cout<< "Woof, I am "<< str << " dog " << m_name << endl;}
};

class yellowdog : public dog {
    public:
        yellowdog(string name):dog(name, "yellow") {}
};

int main ()
{
  yellowdog mydog("Bob");
}

输出:
Woof, I am yellow dog Bob

/*
解决方法 2:
使用私有静态成员函数,不同派生类可执行不同操作
*/
class dog {
    public:
        ...
        dog(string name, string woof) {m_name = name; bark(woof);}
        dog(string name) {m_name = name; bark( getMyColor() );}
        void bark(string str) { cout<< "Woof, I am "<< str << " dog " << m_name << endl;}
    private:
        static string getMyColor() {return "just a";}
};

class yellowdog : public dog {
    public:
        yellowdog(string name):dog(name, getMyColor()) {}
    private:
        static string getMyColor() {return "yellow";}  //Why static?
};

int main ()
{
  yellowdog mydog("Bob");
}
OUTPUT:
Woof, I am yellow dog Bob

原文地址:https://www.cnblogs.com/logchen/p/10165346.html

时间: 2024-11-17 03:38:24

C++进阶--构造函数和析构函数中的虚函数的相关文章

构造函数和析构函数中的虚函数

构造派生类对象时首先运行基类构造函数初始化对象的基类部分.在执行基类构造函数时,对象的派生类部分是未初始化的.实际上,此时对象还不是一个派生类对象. 撤销派生类对象时,首先撤销它的派生类部分,然后按照与构造顺序的逆序撤销它的基类部分. 在这两种情况下,运行构造函数或析构函数的时候,对象都是不完整的.为了适应这种不完整,编译器将对象的类型视为在构造或析构期间发生了变化.在基类构造函数或析构函数中,将派生类对象当作基类类型对象对待. 构造或析构期间的对象类型对虚函数的绑定有影响. 如果在构造函数或析

在构造函数和析构函数中调用虚函数------新标准c++程序设计

在构造函数和析构函数中调用虚函数不是多态,因为编译时即可确定调用的是哪个函数.如果本类有该函数,调用的就是本类的函数:如果本类没有,调用的就是直接基类的函数:如果基类没有,调用的就是间接基类的函数,以此类推.例如: #include<iostream> using namespace std; class A { public: virtual void hello(){cout<<"A::hello()"<<endl;} virtual void

[C++]在构造函数及析构函数中调用虚函数

(ISO/IEC 14882:2011 section 12.7.4): Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2).When a virtual function is called directly or indirectly from a constructor or from a destructor, inc

EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #include <iostream> using namespace std; class cls1{ public: cls1(){ newMake(); }; ~cls1(){ deleteIt(); }; virtual void newMake(){ cout<<"cls1 make"<<endl; } virtual void deleteIt()

第八章:不要在构造和析构函数中使用虚函数

前言 本文将讲解一个新手C++程序员经常会犯的错误 - 在构造/析构函数中使用虚函数,并分析错误原因所在以及规避方法. 错误起因 首先,假设我们以一个实现交易的类为父类,然后一个实现买的类,一个实现卖的类为其子类. 这三个类的对象初始化过程中,都需要完成注册的这么一件事情 (函数).然而,各自注册的具体行为是不同的. 有些人会写出以下这样的代码: 1 class Transaction { 2 public: 3 Transaction(); // 父类构造函数 4 //...... 5 pri

不要在构造和析构函数中使用虚函数

前言 本文将讲解一个新手 C++ 程序员经常会犯的错误 - 在构造/析构函数中使用虚函数,并分析错误原因所在以及规避方法. 错误起因 首先,假设我们以一个实现交易的类为父类,然后一个实现买的类,一个实现卖的类为其子类. 这三个类的对象初始化过程中,都需要完成注册的这么一件事情 (函数).然而,各自注册的具体行为是不同的. 有些人会写出以下这样的代码: 1 class Transaction { 2 public: 3 Transaction(); // 父类构造函数 4 //...... 5 p

C++:构造函数和析构函数能否为虚函数

原文:http://blog.csdn.net/xhz1234/article/details/6510568 C++:构造函数和析构函数能否为虚函数? 简单回答是:构造函数不能为虚函数,而析构函数可以且常常是虚函数. (1) 构造函数不能为虚函数 让我们来看看大牛C++之父 Bjarne Stroustrup 在<The C++ Programming Language>里是怎么说的: To construct an object, a constructor needs the exact

Effective C++ Item 09-绝不在构造函数和析构函数中调用virtual函数

Item 09-绝不在构造函数和析构函数中调用virtual函数(Never call virtual functions during construction or destruction) Why? 由于base class构造函数的执行更早于derived class构造函数,当base class构造函数执行derived class的成员变量尚未初始化.如果期间调用的virtual函数下降至derived class阶层,要知道derived class的函数几乎必然取用local成

构造函数,析构函数是否为虚函数

1:构造函数不能为虚函数 1):虚函数是用父类指针引用子类对象用的,(父类)构造函数在被调用的时候,子类对象还没被创建,不能用虚函数 2):虚函数是通过vtable来调用的,vtable存在于对象的存储空间中,构造函数被调用的时候,对象还未生成,空间未分配, 因此构造函数不能为虚函数 2:析构函数可以为虚函数,而且尽量设置为虚函数 1):释放对象的时候,先调用子类的析构函数,再调用父类的析构函数. 非虚函数是静态绑定的,当去释放一个指向子类对象的父类指针时,如果父类的析构函数是非虚函数,这时就只