天天看點

Effective c++ 學習筆記(五)

條款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;
}
           

總結

編譯器會為類聲明構造函數、拷貝構造函數、拷貝運算符和析構函數。

繼續閱讀