条款05:了解c++默默编写并调用哪些函数
编译器会为类声明构造函数、拷贝构造函数、拷贝运算符和析构函数。
class Empty { }; 等价于: class Empty { public: Empty() { } //构造函数 Empty(const Empty &rhs) { } //拷贝构造函数 ~Empty() { } //析构函数 Empty &operator = (const Empty &rhs) { } //拷贝运算符 };
- 这些函数被调用时,才会被编译器创建出来。
- 如果类中含有引用成员、const成员,则必须自己定义拷贝操作符。
- 编译器为类产生的析构函数是非虚函数,除非这个类的基类声明有虚析构函数。
- 编译器产生的拷贝构造函数和拷贝运算符,仅将对象的non-static成员变量拷贝到目标对象。
#include <iostream> #include <string> using namespace std; template<typename T> class student{ public: student(const string &name, const T& age); private: string m_name; T m_age; }; template<typename T> student<T>::student(const string &name, const T& age):m_name(name),m_age(age) { } int main(){ student<int> stu("Jenny", 3); student<int> stu2(stu); //编译器自动创建拷贝构造函数 system("pause"); return 0; }上例类中含有构造函数,编译器不再为类创建默认构造函数。
student中没有声明拷贝构造函数和拷贝操作符,在需要调用时,编译器会自动创建。
上例中当m_name是引用,m_age是const T时:
#include <iostream> #include <string> using namespace std; template<typename T> class student{ public: student(string &name, const T& age); //string不能是const,因为m_name是引用non const string private: string& m_name; const T m_age; }; template<typename T> student<T>::student(string &name, const T& age):m_name(name),m_age(age) { } int main(){ string str1("Jenny"); student<int> s1(str1, 3); string str2("Dave"); student<int> s2(str2, 3); s1 = s2; //编译会出错,因为operator = 此时不可用 system("pause"); return 0; }