條款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;
}
總結
編譯器會為類聲明構造函數、拷貝構造函數、拷貝運算符和析構函數。