Advanced C++ --- Compiler Generated Functions
C++在C的基础上添加了很多新的特性,其中包括了很被人熟知的OOP,范型编程等,但是很多大家不知道的应该是我们的C++编译器在什么时候为我们编写的类自动生成什么函数(赋值函数,析构函数,构造函数等),这些函数的内部又是如何操作的,这里我们就说说C++中类的Costructer, Destructer和赋值操作的自动生成。
首先还是上一段代码:
#include<iostream> #include<string> using namespace std; class dog{ public: string m_name; dog(string name = "Bob"){m_name = name; cout << name << " is born." << endl;} ~dog(){cout << m_name << " is destroyed.\n" << endl;} }; int main(){ dog dog1("Henry"); dog dog2; dog2 = dog1; }
其输出为:
Henry is born. Bob is born. Henry is destroyed. Henry is destroyed.
在main函数中的第一句,我们显式调用了Dog类的构造函数,所以第一句很容易解释,main函数的第二句是隐式调用,那么C++中到底是默认调用哪个函数进行初始化的?根据output我们很容易知道这句调用了类的唯一构造函数,所以输出的是bob,那么有些人会问了,如果我不编写构造函数又会怎么样呢?会不会编译错误呢?答案是不会,依然会编译通过,但是自己的默认构造函数会将类的变量进行初始化,比如string初始化为空字符串,int初始化为0,那么我们的输出就只有一句:
is destroyed.
还有一个问题,如果我们的类中的成员变量不是基本类型,而是一个类的实例又会怎么样?我在这里添加了这一部分以供参考:
#include<iostream> #include<string> using namespace std; class dogFood{ public: string food_name; dogFood(string name = "meat"){food_name = name; cout << food_name << " is born" << endl;} ~dogFood(){cout << food_name << " is destroyed." << endl;} }; class dog{ public: dogFood m_food; string m_name; //dog(string name = "Bob"){m_name = name; cout << name << " is born." << endl;} ~dog(){cout << m_name << " is destroyed.\n" << endl;} }; int main(){ //dog dog1("Henry"); dog dog2; //dog2 = dog1; }
我们在这里声明了一个类对象dogFood,那么这个main函数的输出又会是什么呢?
meat is born is destroyed. meat is destroyed.
是不是发现很简单?其实每次如果没有定义构造函数的情况下显示调用,C++ Compiler会初始化类中的每一个变量(包括非基本类型的变量),类实例变量会调用他的构造函数,如果没有的话,问题就回到了我们一开始说的,自己生成一个默认的构造函数。这里还要小提一下,C++ Compiler只有在调用的时候才会生成function,比如,只有初始化才会生成构造函数,只有在销毁对象的时候生成析构函数,赋值的时候生成copy assigment等等。这样做也是考虑到执行效率的问题。
那么如果在自动生成的策略下出现问题怎么办?一个很常见的问题就是,copy assignment中如果有一个不可copy的变量,比如我们在string m_name前加上引用(string& m_name),这样的话,编译器将会报错,因为引用是不能进行赋值的。同样的道理,不能复制的类也是不能在STL的container中比如vector,map等中使用,因为这些容器都是需要类支持赋值的,所以如果想要支持vector,需要自己编写赋值操作。
posted on 2015-12-30 15:46 RookieCoder 阅读(305) 评论(0) 收藏 举报
浙公网安备 33010602011771号