建構子與解構子
Prerequisites:
建構子
語法
public:
類別名() {
}
- 與類別的名字相同
- 沒有返回值
- 權限是public
- 可以有參數,參數也可以有預設值
參數為空的建構子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
const char* name_;
Student() {
cout << "無參數建構子被呼叫:物件已初始化" << endl;
}
};
int main() {
Student student;
return 0;
}
無參數建構子被呼叫:物件已初始化
解構子
物件記憶體釋放前,會執行解構子。
語法
public:
~類別名() {
}
~Student(){
}
- 與類別的名字相同,前面加上~
- 沒有返回值
- 權限是public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
const char* name_;
Student() {
cout << "無參數建構子被呼叫:物件已初始化" << endl;
}
~Student() {
cout << "呼叫解構子" << endl;
}
};
int main() {
Student student;
return 0;
}
無參數建構子被呼叫:物件已初始化
呼叫解構子
呼叫有參數的建構子
語法:
類別 物件名(參數1)
Student student("Mary");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
const char* name_;
Student() {
cout << "無參數建構子被呼叫:物件已初始化" << endl;
}
Student(const char* name) {
name_ = name;
cout << "一個參數建構子 name_ = " << name_ << endl;
}
};
int main() {
Student student("Mary");
return 0;
}
一個參數建構子 name_ = Mary
建構子參數只有一個,可使用指派運算子
建構子參數只有一個,可使用指派運算子=,呼叫只有一個參數的建構子
類別 物件名 = 參數
Student student = "Mary";
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
const char* name_;
Student() {
cout << "無參數建構子被呼叫:物件已初始化" << endl;
}
Student(const char* name) {
name_ = name;
cout << "一個參數建構子 name_ = " << name_ << endl;
}
};
int main() {
Student student= "Mary";
return 0;
}
一個參數建構子 name_ = Mary
注意事項
建構子解構子自動生成
若沒實作建構子/解構子,編譯器會自動生成空的建構子與解構子,若實作建構子,不管建構子有沒有參數,編譯器不會自動生成空的建構子或解構子
如果沒有實作空的建構子,只實作有參數的建構子,以下程式碼編譯不過。
以下程式碼在主程式main函式,會尋找空的建構子。
Student student;
以下程式碼編譯不過
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
const char* name_;
Student(const char* name) {
name_ = name;
cout << "一個參數建構子 name_ = " << name_ << endl;
}
};
int main() {
Student student;
return 0;
}
不要用變數名()建立物件
以下程式碼,會編譯成功,但不會呼叫建構子,建立物件失敗。
編譯器認為是呼叫函式名為student()的函式,回傳值類型是Student。
Student student();
執行結果為空,沒有印出”無參數建構子被呼叫:物件已初始化”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
const char* name_;
Student() {
cout << "無參數建構子被呼叫:物件已初始化" << endl;
}
};
int main() {
Student student();
return 0;
}
建構子初始化
使用建構子初始化成員變數。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Student {
public:
const char* name_;
int id_;
Student() {
name_ = nullptr;
id_ = 0;
}
};
int main() {
Student s;
if (s.name_ == nullptr) {
cout << "name_ is nullptr" << endl;
} else {
cout << "name_: " << s.name_ << endl;
}
cout << s.id_ << endl;
return 0;
}
name_ is nullptr
0
使用init()初始化成員變數
以下每個建構子都呼叫init()初始化成員變數,若有多個成員變數要初始化,可以全寫在init()中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
const char* name_;
Student() {
init();
cout << "無參數建構子被呼叫:物件已初始化" << endl;
}
Student(const char* name) {
init();
name_ = name;
cout << "一個參數建構子 name_ = " << name_ << endl;
}
void init() {
name_ = nullptr;
}
};
int main() {
Student student= "Mary";
return 0;
}
一個參數建構子 name_ = Mary