C++复习-01 (想到哪写到哪系列)
-
C++析构函数为什么要写成virtual
class Base { public: Base(){cout << "Base" << endl;} ~Base(){cout << "~Base" << endl;} //void print(){cout << "This is Base" << endl;} }; class Device : public Base { public: Device(){cout << "Device" << endl;} ~Device(){cout << "~Device" << endl;} }; //main fun call Base * p = new Device; delete p; //output Base Device ~Base
看上面的案例,子类的析构函数没有被调用,在子类中析构函数要被释放的资源将不能被正确的释放。(为什么会这样?C++多态的实现原理中具体说)
-
某个函数在基类中声明为virtual,那么在所有的派生类中该函数都是virtual,而不需要再显式地声明为virtual,测试案例如下:
class Base { public: Base(){cout << "Base" << endl;} virtual ~Base(){cout << "~Base" << endl;} virtual void print(){cout << "This is Base" << endl;} }; class Device : public Base { public: Device(){cout << "Device" << endl;} ~Device(){cout << "~Device" << endl;} void print(){cout << "This is Device" << endl;} }; class Device1 : public Device { public: Device1(){cout << "Device1" << endl;} ~Device1(){cout << "~Device1" << endl;} void print(){cout << "This is Device1" << endl;} }; //main fun call Base * p = new Device1; p->print(); delete p; //output Base Device Device1 This is Device1 ~Device1 ~Device ~Base
很显然,在Device类中没有使用virtual关键字,但是在Device1的 print()和析构函数都正确调用
-
函数返回值如果是引用类型,一定不要返回局部变量
//错误示例 int & print() { int aaa = 7; return aaa; }
Primer Plus:"由于aaa对象是局部变量,在函数结束时将被删除,因此引用将指向 一个不存在的对象。 "
问:这么基础为什么写出来呢?
答:我之前一直认为,当返回引用后,只要返回的引用被接收,那么代表aaa对象还在被使用,不会被干掉,其实在大括号结束的时候它的生命周期已经over
-
运算符重载
对于非成员重载运算符函数来说,运算符表达式左边的操作数对应于运算符函数的第一个参数,运算符表达式右边的操作数对应于运算符函数的第二个参数。
对于成员成员重载运算符函数来说,运算符表达式左面的操作数对应调用对象(类的一个对象),运算符右边的对象是作为参数被传递的对象。
class Base { double m_v; public: Base(double v){m_v = v;} void print(){cout << m_v << endl;} Base operator *(double tt) const { double temp = (this->m_v) * (tt); return Base(temp); } }; //in main func Base te = 23.7 * d; //error ① Base te = d * 23.7; //right ②
对于上面定义了*重载的类中,操作符的左面只能是类对象。要想第一种调用成功,有两种方法,如下:
*** 注意:两种方法不能同时存在
//方法一:在类的外面定义如下函数 Base operator *(double m, const Base &b) { return b * m; } //方法二:使用友元函数 friend Base operator *(double m, const Base &b); //在类中添加 Base operator *(double m, const Base &b) //类的外面定义 { return Base(b.m_v * m); }