C++基礎建構函式(constructor)

weixin_33866037發表於2017-12-17

建構函式定義

C++中的類可以定義與類名相同的特殊成員函式,這種與類名相同的成員函式叫做建構函式,建構函式在定義時可以有引數;但是是沒有任何返回型別的宣告。

建構函式語法

class 類名
{
public:
    類名(引數列表)
{
   函式體
}
private:
   資料成員
};

建構函式的特點:

  1. 函式名稱就是當前的類名稱。
  2. 建構函式沒有返回值

建構函式的呼叫

顯示呼叫建構函式

Student studentOne = Student("st1",20);

隱式呼叫建構函式

Student studentTwo("st2",21);

new建立指標

建立一個Student物件,並將該物件的地址賦給studentThree指標,物件沒有名稱,但是可以通過指標來管理物件。

Student *studentThree = new Student("St3",18);

建構函式的作用

初始化物件的資料成員。

建構函式的種類

預設建構函式

預設建構函式實在未提供顯示初始化值用來建立物件的,主要用於下面這種情況.

Student stu;

預設建構函式可能如下函式:

Student::Student(){}

注意:

  1. 只有當且僅當類沒有定義任何建構函式的情況下,編譯器才會建立預設建構函式。
    2.當類中定義了建構函式,但是沒有提供預設建構函式,下面的宣告是錯誤的:所以如果想使用預設建構函式必須過載來定義一個沒有引數的建構函式。
Student()
    {
        name = "";
        age = 0;
    }

無參建構函式

編譯器本身會提供一個無參的建構函式,但是這個系統的無參建構函式實際意義沒有太大,因為系統預設的無參建構函式沒有給成員屬性提供初始值,而是會隨機分配初始值,因此通常自定義的無參建構函式會對類中的資料進行初始值。

class Student
{
public:
    Student()
    {
        s_Name = "default name";
    }
    string getName()
    {
        return s_Name;
    }
private:
   string s_Name;
};

int main(int argc, char *argv[])
{
    Student stu;
    cout<<"name: " << stu.getName() <<endl;
    return 0;
}

自定義帶引數建構函式

通過初始化列表實現構造引數,就是在引數列表的後面加冒號“:”

  Student(string s_Name):s_Name(s_Name){}

預設引數得建構函式
預設引數的建構函式 需要防止呼叫的二義性,建構函式的第n個引數有預設值,則其後的所有引數都有預設值

 Student(int id ,string name = "default baxiang",int age = 0){
          s_ID = id;
          s_Name = name;
          s_age = age;
    }

包含成員物件的建構函式

個類的物件時,應先呼叫其建構函式。但是如果這個類有成員物件,則要先執行成員物件自己所屬類的建構函式,當全部成員物件都執行了自身類的建構函式後,再執行當前類的建構函式

<類名>::<類名>(<總參數列>):<成員物件1>(<形參表1>), <成員物件2>(<形參表2>),……
{ //函式體 }
class SDate
{
public:
    SDate(int y,int m,int d);
    void show();


private:
    int year,month,day;
};
SDate::SDate(int y,int m,int d)
{
    year = y;
    month = m;
    day = d;
}
void SDate::show()
{
        cout<<year<<month<<day<<endl;
 }

class Student
{
public:
   Student(string name,int y,int m,int d);
   void printInfo();
private:
    string s_Name;
    SDate birthday;
};

Student:: Student(string name,int y,int m,int d):birthday(y,m,d){
    s_Name = name;
}

拷貝建構函式(複製建構函式)

class 類名
{
public:
          類名:(類名 & 變數名)
         {
           函式體
         }
};

使用一個物件初始化另外一個新的物件

class Student
{
public:
    Student(string n,int a){
        name =n;
        age = a;
    }
    Student(Student &s){
        name = s.name;
        age = s.age;
    }
   void printInfo()
   {
       cout<<"name " <<name << " age "<<age <<endl;
   }
private:
    string name;
    int age;
};

int main(int argc, char *argv[])
{
    Student student("baxiang",18);
    student.printInfo();
    Student copyS(student);
    copyS.printInfo();
    return 0;
}

物件作為函式引數
當引數為物件是 會呼叫拷貝建構函式

class Student
{
public:
    Student(string n,int a){
        name =n;
        age = a;
    }
    Student(Student &s){
        cout<<"copy func"<<endl;
        name = s.name;
        age = s.age;
    }
    void printInfo()
    {
        cout<<"name " <<name << " age "<<age <<endl;
    }
private:
    string name;
    int age;
};

void printStudent(Student s)
{
    s.printInfo();
}
int main(int argc, char *argv[])
{
    Student student("baxiang",18);
    printStudent(student);
    return 0;
}

淺拷貝與深拷貝

淺拷貝是隻拷貝指標地址,意思是淺拷貝指標都指向同一個記憶體空間,當原指標地址所指空間被釋放,那麼淺拷貝的指標全部失效。
深拷貝是先申請一塊跟被拷貝資料一樣大的記憶體空間,把資料複製過去。這樣拷貝多少次,就有多少個不同的記憶體空間,資料之間相互獨立互不影響。

相關文章