1. 拷贝构造函数
(1) 主要用于类对象之间的复制
(2) 是一种特殊的构造函数,函数的名称必须和类名称一致,并且它的唯一一个参数是本类型的一个引用变量,该参数是const 类型,不可变的。
(3) 当一个已初始化过了的自定义类对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类 的对象需要拷贝时,拷贝构造函数将会被调用,例如以下情况都会调用拷贝构造函数:
一个对象以值传递方式传入函数
一个对象以值传递方式从函数返回
一个对象需要通过另外一个对象进行初始化
(4)如果类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,改拷贝构造函数完成对 象之间的位拷贝,位拷贝又称浅拷贝。
(5)浅拷贝和深拷贝:在某些状况下,类内成员变量需要动态开辟堆内存。如果用默认拷贝构造函数的话会出现,两个变量同时 指向一个内存块。这就出现了问题,当一个变量将内存释放了,另外一个指针就是野指针了,出现运行错误。
2. 模板函数和模板类 (泛型编程)
(1) 模板函数:
格式 : template <class xx,class ...> 返回类型 函数名 (形参列表)
{ 函数体 }
其中template是关键字 ,class 可以用typename代替 ,<> 里面的叫做模板形参,和函数形参很像,模板形参声明好后, 后面的函数形参、函数体等(使用内置类型的地方)就都可以调用改形参类型。
调用的时候就是普通调用函数的方式,编译器会根据你调用时的类型(实例化)来决定模板形参。
(2)类模板: 有一点不同就是,在实例化的时候必须要加上类型,比如类模板A,实例化定义的时候要 A<int> a; 这样写。
(3)在 类模板 成员外定义类内的成员模板函数
template<模板形参列表> 函数返回类型 类名<模板形参名>::函数名(参数列表){函数体},
template<class T1,class T2> void A<T1,T2>::h(){}。
PS: typename 是一个关键字,用于指出模板声明中的非独立名称是类型名,而非变量名,此处的class可与typename互换。
(4)模板类的继承:注意以下几点
如果父类定自义了构造函数,记得子类要使用构造函数列表来初始化父类
继承的时候,如果子类不是模板类,则必须指明当前继承父类的类型用 : Perent<XX> ,因为要分配内存
继承的时候,如果子类是模板,要么指定父类类型,要么用子类的泛型(class T)来指定父类
(5)关于模板形参还有一些说明:( 类型) 的模板新参和 (非类型) 的模板形参两种
如 template<class T,int a>class B { } 其中 int a 就是非类型的模板形参。
非类型的模板形参在模板定义的内部是常量值 ( 即使用时要带入一个常量 变量是不行的 )
注意 非类型的模板参数可以是指针,但该指针必须指向外部链接对象(从另外一个 .cpp extern 过来的对象)