今天开始看effective C++了,感觉写的不错,特此用自己的语言记录一下加深印象~
1.得了解C++编译器会默认编写并调用哪些函数
//当声明一个空类时,编译器会为这个类默默编写4个函数并调用他们以便实现类的功能 class A { }; //在编译器的支持下,上面这个空类等价于下面这个类 class A { public: A(){}; //default构造函数 A(const A&){}; //拷贝构造函数 A& operator=(const A&){}; //拷贝赋值操作符 ~A(){}; //析构函数 };
2.C++允许让一个指向父类的指针指向这个父类的派生类,但并不允许指向一个派生类的指针指向其父类,这么做会导致未定义的结果。
class A { public: int a; }; class B : public A { public: int b; }; A* p=new A; p=new B; //从上面两个类来看,分配给类A的实例的内存占4个字节(32bit),而分配给类B的实例的内存占8个字节 //那么让p指向一个类B的实例后,指针p只能访问继承来的前四个字节 B* p2=new B; p2=new A; //上面这么做的结果就是未定义
3.C++通过引入虚函数实现多态性,这样就可以用指向父类的指针去执行各个派生类各自的行为了。同时也要注意为多态基类声明虚析构函数(多态基类就是类中至少有一个虚函数,因为有一个虚函数就表示期待被继承),同时也并不是所有类都得用虚析构函数,只要当这个类要被继承时(其中有虚函数)使用虚析构函数,目的就是使得派生类的实现得以客制化(当一个派生类对象被一个基类的指针delete时,不会有内存泄漏)。
#include <iostream> using namespace std; class A { public: A(){cout<<"A constructor"<<endl;}; ~A(){cout<<"A destructor"<<endl;}; virtual void fun(){cout<<"A"<<endl;}; //virtual ~A(){cout<<"A destructor"<<endl;}; }; class B : public A { public: B(){cout<<"B constructor"<<endl;}; ~B(){cout<<"B constructor"<<endl;}; void fun(){cout<<"B"<<endl;}; }; int main() { A* p=new B; p->fun(); delete p; //会出现未定义行为,必须给A类加上一个虚析构函数 return 0; }
4.常说的浅拷贝是指编译器默认生成的拷贝函数(实质上是将内存复制过去),如果要是这个类里有指针就不好办了。这个时候我们就会有深拷贝这个说法了,深拷贝就是我们重新写一个拷贝构造函数,但是要注意的是如果我们一旦重写自己的拷贝构造函数,在你的代码几乎出错的时候编译器也不会告诉你。
时间: 2024-11-08 18:46:02