(二)C++中的類與建構函式
C++中的類與建構函式
一、C++中類的常用寫法
1、在標頭檔案中宣告類的屬性和方法
如:MyTeacher.h
//防止重複引入 #pragma once class MyTeacher{ private: char* name; int age; public: void setName(char* name); char* getName(); void setAge(int age); int getAge(); };
2、在原始檔中(.cpp)實現對應的方法
如:MyTeacher.cpp
#define _CRT_SECURE_NO_WARNINGS #include "MyTeacher.h" #include <iostream> void MyTeacher::setName(const char* name) { this->name = new char[100]; strcpy(this->name, name); } char* MyTeacher::getName() { return this->name; } void MyTeacher::setAge(int age) { this->age = age; } int MyTeacher::getAge() { return this->age; }
3、在具體C++程式碼中使用
如:test.cpp
#include "MyTeacher.h" using namespace std; void main() { MyTeacher t; t.setName("Jack"); t.setAge(25); cout << t.getName() << "," << t.getAge() << endl; getchar(); }
二、C++中類的建構函式、解構函式、拷貝建構函式
1、建構函式
- C++類預設有無參建構函式,重寫無參建構函式會覆蓋預設的無參建構函式
- 有參建構函式會覆蓋預設無參建構函式
class Teacher{ private: char* name; int age; public: //無參建構函式 Teacher(){ cout << "無參建構函式" << endl; } //有參建構函式 Teacher(char *name,int age){ this->name = name; this->age = age; cout << "有參建構函式" << endl; } }; void main(){ Teacher t1; Teacher t2("Rose",23); //有參建構函式另一個呼叫方式 Teacher t3 = Teacher("jack",21); getchar(); }
2、解構函式
當物件要被系統釋放時,解構函式會被呼叫,一般用作善後處理
class Teacher{ private: char* name; int age; public: //無參建構函式 Teacher(){ this->name = (char*)malloc(100); strcpy(name,"Hello,Jack Teacher"); this->age = 25; cout << "無參建構函式" << endl; } //解構函式 ~Teacher(){ cout << "解構函式" << endl; free(this->name); } //有參建構函式 Teacher(char *name,int age){ this->name = name; this->age = age; cout << "有參建構函式" << endl; } }; void func(){ Teacher t1; } void main(){ func(); getchar(); }
3、拷貝建構函式
3.1 淺拷貝
- 預設拷貝建構函式,就是值拷貝(淺拷貝)
- 淺拷貝拷貝的是指標的地址(同一塊記憶體區域)
using namespace std; class Teacher { private: char* name; int age; public: //有參建構函式 Teacher(char *name, int age) { this->name = name; this->age = age; cout << "有參建構函式" << endl; } //解構函式 ~Teacher() { cout << "解構函式" << endl; free(this->name); } //拷貝建構函式 Teacher(const Teacher &obj) { this->name = obj.name; this->age = obj.age; cout << "拷貝建構函式" << endl; } void myprint() { cout << name << "," << age << endl; } }; void main() { Teacher t1((char*)"rose", 30); Teacher t2 = t1; t2.myprint(); getchar(); }
輸出
有參建構函式 拷貝建構函式 rose,30
- 淺拷貝有可能會出現第二次釋放變數導致出現異常的情況
例如:出現異常的情況
using namespace std; class Teacher { private: char* name; int age; public: //有參建構函式 Teacher(char *name, int age) { int len = strlen(obj.name); this->name = (char*)malloc(len+1); strcpy(this->name,name); this->age = age; cout << "有參建構函式" << endl; } //解構函式 ~Teacher() { cout << "解構函式" << endl; free(this->name); } void myprint() { cout << name << "," << age << endl; } }; void func(){ Teacher t1((char*)"rose", 30); Teacher t2 = t1; t2.myprint(); } void main() { func(); getchar(); }
3.2 深拷貝
深拷貝拷貝的是指標指向的資料內容(兩塊記憶體區域)
using namespace std; class Teacher { private: char* name; int age; public: //有參建構函式 Teacher(char *name, int age) { int len = strlen(obj.name); this->name = (char*)malloc(len+1); strcpy(this->name,name); this->age = age; cout << "有參建構函式" << endl; } //解構函式 ~Teacher() { cout << "解構函式" << endl; free(this->name); } //拷貝建構函式(深拷貝) Teacher(const Teacher &obj) { //複製name屬性 int len = strlen(obj.name); this->name = (char*)malloc(len+1); strcpy(this->name,obj.name); this->age = obj.age; cout << "拷貝建構函式" << endl; } void myprint() { cout << name << "," << age << endl; } }; void func(){ Teacher t1((char*)"rose", 30); //宣告時會被呼叫 Teacher t2 = t1; //下面這種方式不會被呼叫 //Teacher t1; //Teacher t2; //t1 = t2; t2.myprint(); } void main() { func(); getchar(); }
3.3 拷貝建構函式被被呼叫的場景
- 宣告時賦值
- 作為引數傳入,實參給形參賦值
- 作為函式返回值返回,給變數初始化賦值
4、建構函式屬性初始化列表
建構函式屬性初始化列表的格式為:
[建構函式名稱]([本類中屬性列表],[第一個類物件的屬性列表],[第二個類物件的屬性列表]):[第一個類物件]([第一個類物件的屬性列表]),[第二個類物件]([第二個類物件的屬性列表]){ }
示例如下:
class Teacher{ private: char* name; public: Teacher(char* name){ this->name = name; cout << "Teacher有參建構函式" << endl; } ~Teacher(){ cout << "Teacher解構函式" << endl; } char* getName(){ return this->name; } }; class Student{ private: int id; Teacher t1; public: Student(int id,char* t1_name) : t1(t1_name){ this->id = id; cout << "Student有參建構函式" << endl; } ~Student(){ cout << "Student解構函式" << endl; } void myprint(){ cout << this->id << "同學的老師是" << t1.getName() << endl; } }; void func(){ Student t1(16,(char*)"Jack"); t1.myprint(); } void main(){ func(); getchar(); }
三、C++中的new 和 delete的使用
C++中通過new和delete來進行動態記憶體分配,new 和delete成對出現
C++中在使用new和delete會對應呼叫建構函式和析構引數,通過C中的malloc方式則不會呼叫建構函式和解構函式
class Teacher{ private: char* name; public: Teacher(char* name){ this->name = name; cout << "Teacher有參建構函式" << endl; } ~Teacher(){ cout << "Teacher解構函式" << endl; } void setName(char* name){ this->name = name; } char* getName(){ return this->name; } }; void func(){ //初始化,返回指標地址 Teacher *t1 = new Teacher((char*)"Jack"); //使用 //釋放 delete t1; int *p2 = new int[10]; p2[0] = 11; //釋放陣列 delete p2; } void main(){ func(); getchar(); }