上一篇我們學(xué)習(xí)了C++的命名空間拔创,這篇我們來了解一下C++的構(gòu)造和析構(gòu)函數(shù)
廢話不多說,開始擼碼
正文
構(gòu)造函數(shù)富蓄、析構(gòu)函數(shù)剩燥、拷貝構(gòu)造函數(shù)
來個(gè)簡單的例子,了解一下構(gòu)造和析構(gòu)的寫法
class Teacher{
public:
int age;
public:
Teacher(){
cout << "無參構(gòu)造函數(shù)" << endl;
}
~Teacher(){
cout << "析構(gòu)函數(shù)" << endl;
}
};
當(dāng)類沒有構(gòu)造函數(shù)的時(shí)候默認(rèn)會有一個(gè)無參的構(gòu)造函數(shù)立倍,構(gòu)造函數(shù)的作用是初始化變量灭红,析構(gòu)函數(shù)則釋放資源
既然有了構(gòu)造函數(shù),那怎么創(chuàng)建對象呢口注?
無參構(gòu)造: Teacher t;
有參構(gòu)造: Teacher t1("lypop", 21);
Teacher t2 = Teacher("lypop", 21);
創(chuàng)建指針: Teacher *tt = new Teacher("lypop",21);
對于析構(gòu)函數(shù)的調(diào)用变擒,我們將創(chuàng)建放在一個(gè)方法里面,當(dāng)方法執(zhí)行結(jié)束便會執(zhí)行析構(gòu)函數(shù)
class Teacher{
private:
char *name;
int age;
public:
Teacher(){
this->name = (char*)malloc(100);
strcpy(name, "lypop");
age = 20;
cout << "無參構(gòu)造函數(shù)" << endl;
}
//析構(gòu)函數(shù)
~Teacher(){
cout << "析構(gòu)" << endl;
//釋放內(nèi)存
free(this->name);
}
};
void func2(){
Teacher t;
}
我們只需要在析構(gòu)函數(shù)中釋放相應(yīng)的資源
除了構(gòu)造函數(shù)和析構(gòu)函數(shù)疆导,類里面有個(gè)默認(rèn)的拷貝構(gòu)造函數(shù),它只是一種值拷貝葛躏,當(dāng)類中有指針屬性的時(shí)候容易發(fā)生崩潰澈段。所以當(dāng)我們類中有指針需要在析構(gòu)函數(shù)釋放資源的時(shí)候,拷貝構(gòu)造函數(shù)都使用深拷貝
下面來看一下值拷貝(淺拷貝)
class Teacher{
private:
char *name;
int age;
public:
Teacher(char *name, int age){
this->name = (char*)malloc(100);
strcpy(this->name,name);
this->age = age;
cout << "有參構(gòu)造函數(shù)" << endl;
}
~Teacher(){
cout << "析構(gòu)" << endl;
//釋放內(nèi)存
free(this->name);
}
};
void func(){
Teacher t1("rose", 20);
Teacher t2 = t1;//這時(shí)候會調(diào)用默認(rèn)的拷貝構(gòu)造函數(shù)
}
當(dāng)func執(zhí)行完畢之后就會調(diào)用兩次析構(gòu)舰攒,因?yàn)橹皇呛唵蔚闹悼截惏芨唬琻ame指針指向的是同一塊內(nèi)存地址,當(dāng)?shù)谝粋€(gè)被釋放掉在釋放第二個(gè)的時(shí)候就會出錯(cuò)摩窃。所以需要解決這種就需要深拷貝兽叮,也就是重寫拷貝構(gòu)造函數(shù)為name重新開辟一塊內(nèi)存地址
//深拷貝
Teacher(const Teacher &obj){
//復(fù)制name屬性
int len = strlen(obj.name);
this->name = (char*)malloc(len+1);
strcpy(this->name,obj.name);
this->age = obj.age;
}
拷貝構(gòu)造函數(shù)被調(diào)用的場景:
- 聲明時(shí)賦值
- 作為參數(shù)傳入芬骄,實(shí)參給形參賦值
- 作為函數(shù)返回值返回鹦聪,給變量初始化賦值
C和C++創(chuàng)建指針和釋放資源
C 創(chuàng)建 int *p1 = (int*)malloc(sizeof(int) * 10);
釋放 free(p1);
C++創(chuàng)建 int *p2 = new int[10];
釋放 delete[] p2;//釋放數(shù)組指針 delete p;//釋放指針
C++訪問靜態(tài)屬性和方法
通過類名::來訪問,也可以通過類對象來訪問
int Teacher::total = 9;
Teacher::total++;
Teacher::count();
常量對象泽本、常函數(shù)
Teacher *const this;能改變指針指向的內(nèi)容淘太,不能改變指針的值
const Teacher* const this;既不能改變指針的值规丽,又不能改變指針指向的內(nèi)容
常量對象只能調(diào)用常量函數(shù),不能調(diào)用非常量函數(shù)赌莺。常函數(shù)當(dāng)前對象不能被修改冰抢,防止數(shù)據(jù)成員被非法訪問
class Teacher{
void myprint() const{
}
};
void main(){
const Teacher t1("aaa",22);
t.myprint();
system("pause");
}
友元函數(shù)、友元類
友元函數(shù)的實(shí)現(xiàn)艘狭,在友元函數(shù)中可以訪問私有的屬性
class A{
friend void modify_i(A *p, int a);
private:
int i;
};
void modify_i(A *p, int a){
p->i = a;
}
友元類中可以訪問友元對象所在類的所有成員
class A{
friend class B;
private:
int i;
};
class B{
public:
//B這個(gè)友元類可以訪問A類的任何成員
void accessAny(){
a.i = 30;
}
private:
A a;
};
運(yùn)算符重載
-
類外進(jìn)行運(yùn)算符重載
class Point{ public: int x; int y; public: Point(int x = 0, int y = 0){ this->x = x; this->y = y; } void myprint(){ cout << x << "," << y << endl; } }; Point operator+(Point &p1, Point &p2){ Point tmp(p1.x+p2.x,p1.y+p2.y); return tmp; } Point operator-(Point &p1, Point &p2){ Point tmp(p1.x - p2.x, p1.y - p2.y); return tmp; }
-
類內(nèi)進(jìn)行運(yùn)算符重載
class Point{ public: int x; int y; public: Point(int x = 0, int y = 0){ this->x = x; this->y = y; } //成員函數(shù)挎扰,運(yùn)算符重載 Point operator+(Point &p2){ Point tmp(this->x + p2.x, this->y + p2.y); return tmp; } void myprint(){ cout << x << "," << y << endl; } };
-
當(dāng)屬性私有的時(shí)候需要使用友元函數(shù)實(shí)現(xiàn)運(yùn)算符重載
class Point{ friend Point operator+(Point &p1, Point &p2); private: int x; int y; public: Point(int x = 0, int y = 0){ this->x = x; this->y = y; } void myprint(){ cout << x << "," << y << endl; } }; Point operator+(Point &p1, Point &p2){ Point tmp(p1.x + p2.x, p1.y + p2.y); return tmp; }
但是運(yùn)算符重載的本質(zhì)還是函數(shù)的調(diào)用,至此C++的類就總結(jié)到這里缓升,謝謝不耐其煩的看完鼓鲁。