#include <iostream>
#include <string>
using namespace std;
/*
OOP的三大特性:封裝 繼承 多態(tài)
封裝:
將靜態(tài)屬性和動(dòng)態(tài)行為封裝成一個(gè)整體
屬性和行為加以權(quán)限控制:public private protect
public:類外 類內(nèi)都可訪問
private:類外不可訪問 類內(nèi)可以訪問
protect:類外不可訪問 類內(nèi)可以訪問
struct與class的區(qū)別:struct默認(rèn)權(quán)限是public class的默認(rèn)權(quán)限是private
構(gòu)造函數(shù):創(chuàng)建對(duì)象時(shí),為對(duì)象的成員屬性賦初始值,構(gòu)造函數(shù)由編譯器自行調(diào)用
1.無返回值
2.函數(shù)名與類名相同
3.可以進(jìn)行函數(shù)重載,可以有參數(shù)
4.每次創(chuàng)建調(diào)用時(shí)會(huì)自動(dòng)調(diào)用構(gòu)造函數(shù),且只會(huì)調(diào)用一次
構(gòu)造函數(shù)的分類:
1.按參數(shù)分類:有參構(gòu)造函數(shù) 無參構(gòu)造函數(shù)
2.按類型分類:普通構(gòu)造函數(shù) 拷貝構(gòu)造函數(shù)
構(gòu)造函數(shù)的調(diào)用方式: 括號(hào)法 顯示法 隱式轉(zhuǎn)換法
拷貝構(gòu)造函數(shù)調(diào)用時(shí)機(jī):
1.用一個(gè)已有對(duì)象去初始化一個(gè)新的對(duì)象;
2.值傳遞的方式給函數(shù)參數(shù)傳遞值;
3.以值傳遞方式返回局部對(duì)象;
構(gòu)造函數(shù)的調(diào)用規(guī)則:
1.默認(rèn)情況下,c++編譯器至少給一個(gè)類添加3個(gè)函數(shù):默認(rèn)構(gòu)造函數(shù)(無參數(shù)) 默認(rèn)析構(gòu)函數(shù)(無參數(shù)) 默認(rèn)拷貝構(gòu)造函數(shù)(對(duì)屬性進(jìn)行值拷貝)
2.如果用戶定義了有參構(gòu)造函數(shù),c++不會(huì)再提供無參數(shù)的默認(rèn)構(gòu)造函數(shù),但是會(huì)提供默認(rèn)拷貝構(gòu)造函數(shù);
3.如果用戶定義了拷貝構(gòu)造函數(shù),c++不會(huì)再提供其他構(gòu)造函數(shù);
析構(gòu)函數(shù):銷毀對(duì)象前,系統(tǒng)自動(dòng)調(diào)用清理內(nèi)存
1.無返回值
2.函數(shù)名與類名相同,且加上~
3.析構(gòu)函數(shù)無參數(shù),不可以進(jìn)行函數(shù)重載
4.對(duì)象銷毀前會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù)
// 淺拷貝與深拷貝
// 淺拷貝:簡(jiǎn)單的賦值拷貝操作
// 深拷貝:在heap上重新申請(qǐng)空間,進(jìn)行拷貝操作
// 類對(duì)象作為類成員:C++中類的成員可以是另一個(gè)類的對(duì)象,稱為對(duì)象成員
class A{
};
// 創(chuàng)建B對(duì)象時(shí),A和B的構(gòu)造函數(shù)與析構(gòu)函數(shù)誰(shuí)先誰(shuí)后呢?---先調(diào)用對(duì)象成員的構(gòu)造函數(shù),再調(diào)用本類的構(gòu)造函數(shù)
class B{
public:
A a;
};
// 必須使用列表初始化的場(chǎng)景:
注意:成員是按照他們?cè)陬愔谐霈F(xiàn)的順序進(jìn)行初始化的,而不是按照他們?cè)诔跏蓟斜沓霈F(xiàn)的順序初始化的
1.常量成員,因?yàn)槌A恐荒艹跏蓟荒苜x值,所以必須放在初始化列表里面
2.引用類型,引用必須在定義的時(shí)候初始化,并且不能重新賦值,所以也要寫在初始化列表里面
3.沒有默認(rèn)構(gòu)造函數(shù)的類類型,因?yàn)槭褂贸跏蓟斜砜梢圆槐卣{(diào)用默認(rèn)構(gòu)造函數(shù)來初始化,而是直接調(diào)用拷貝構(gòu)造函數(shù)初始化。
// 靜態(tài)成員:在成員變量或成員函數(shù)前加上static關(guān)鍵字
靜態(tài)成員分為:
靜態(tài)成員變量:
1.所有對(duì)象共享同一份數(shù)據(jù)
2.在編譯階段分配內(nèi)存
3.類內(nèi)聲明,類外進(jìn)行初始化
靜態(tài)成語(yǔ)函數(shù):
1.所有對(duì)象共享同一個(gè)函數(shù)
2.靜態(tài)成員函數(shù)只能訪問靜態(tài)成員變量
*/
const double PI = 3.14;
class Circle{
public:
explicit Circle(int r):m_r(r) {}
virtual ~Circle(){}
double calculateZC() {
return 2 * PI * m_r;
}
private:
int m_r;
};
class Student {
public:
Student(string name, int age, int id):m_name(name) ,m_age(age), m_id(id) {}
~Student() {}
void showStudentInfo() {
cout << m_name << " " << m_age << " " << m_id << endl;
}
int m_aa;
private:
string m_name;
int m_age;
int m_id;
};
// 構(gòu)造函數(shù)的分類及調(diào)用
class Person{
public:
// 無參數(shù)的構(gòu)造函數(shù)
Person() {
cout << "not params\n";
}
// 有參的構(gòu)造函數(shù)
Person(int age): m_age(age) {
cout << "display params age\n";
}
// 拷貝構(gòu)造函數(shù)
Person(const Person& p) {
m_age = p.m_age;
cout << "copy constructor has been called\n";
}
// 析構(gòu)函數(shù)
~Person(){
cout << "deconstructor function\n";
}
public:
int m_age;
};
// 1.使用一個(gè)已初始化的對(duì)象來初始化一個(gè)新對(duì)象
void test01() {
Person man(100); // man是一個(gè)已經(jīng)創(chuàng)建好的對(duì)象
Person newman(man); // 調(diào)用拷貝構(gòu)造函數(shù)
Person newman2 = man; // 調(diào)用拷貝構(gòu)造函數(shù)
// Person newman3;
// newman3 = man; // 不調(diào)用拷貝構(gòu)造函數(shù),只是普通賦值操作
}
// 2.以值傳遞的方式給函數(shù)傳遞參數(shù)
void doWork(Person p) {
cout << "doWork: " << (int*)&p << endl;
}
void test02(){
Person p; // 無參構(gòu)造函數(shù)
doWork(p);
}
// 3.以值傳遞的方式返回局部對(duì)象
Person doWork2() {
Person p1;
cout << "doWork2: " << (int*)&p1 << endl;
return p1;
}
void test03() {
Person p = doWork2();
cout << "test03: " << (int*)&p << endl;
}
// 構(gòu)造函數(shù)的調(diào)用規(guī)則
void test04() {
Person p1(18);
// 如果不寫拷貝構(gòu)造函數(shù),編譯器會(huì)自動(dòng)添加拷貝構(gòu)造函數(shù),并且做淺拷貝操作
Person p2(p1);
cout << "p2 age is: " << p2.m_age << endl;
}
// 淺拷貝與深拷貝
class Test {
public:
// 默認(rèn)構(gòu)造函數(shù)
Test() {
cout << "默認(rèn)構(gòu)造函數(shù)\n";
}
// 用戶自定義構(gòu)造函數(shù)
Test(int age, int height) {
m_age = age;
m_height = new int (height);
}
// 拷貝構(gòu)造函數(shù)
Test(const Test& t) {
cout << "Test copy structor\n";
m_age = t.m_age;
m_height = new int (*t.m_height);
}
// 析構(gòu)函數(shù)
~Test() {
cout << "Test deconstructor function\n";
if(m_height) {
delete m_height;
}
}
int m_age;
int* m_height;
};
// 如果對(duì)象的屬性中有在heap上開辟的,一定要自己提供拷貝構(gòu)造函數(shù),不能使用默認(rèn)的拷貝構(gòu)造函數(shù)(淺拷貝)
void test05() {
Test t1(18, 172);
Test t2(t1);
cout << "t1.age=" << t1.m_age << " *t1.m_height=" << *t1.m_height << endl;
cout << "t2.age=" << t2.m_age << " *t2.m_height=" << *t2.m_height << endl;
}
// 類對(duì)象作為類成員
class Phone {
public:
Phone(string name) {
m_name = name;
cout << "Phone constructor\n";
}
~Phone() {
cout << "Phone deconstructor\n";
}
string m_name;
};
class Curry {
public:
Curry(string name, string pName): m_name(name), m_phone(pName) {
cout << "Curry constructor\n";
}
~Curry() {
cout << "Curry deconstructor\n";
}
void playGame(){
cout << m_name << " is using " << m_phone.m_name << " play games\n";
}
string m_name;
Phone m_phone; // 類中成員m_phone是Phone類的對(duì)象時(shí),此時(shí)m_phone稱為對(duì)象成員
};
void test06() {
// 構(gòu)造順序:先調(diào)用對(duì)象成員的構(gòu)造函數(shù),再調(diào)用本類的構(gòu)造函數(shù);析構(gòu)對(duì)象時(shí)順序相反
Curry cu("Curry", "xiaomi");
cu.playGame();
}
// 靜態(tài)成員變量與靜態(tài)成員函數(shù)
// 靜態(tài)成員變量
// 1.所有對(duì)象共享同一份數(shù)據(jù)
// 2.在編譯階段分配內(nèi)存
// 3.類內(nèi)聲明,類外初始化
// 靜態(tài)成員函數(shù)
// 1.所有對(duì)象共享同一個(gè)函數(shù)
// 2.靜態(tài)成員函數(shù)只能訪問靜態(tài)成員變量
class Hello{
public:
static int m_H; // 靜態(tài)成員變量
int m_HO; // 普通成員變量
// 靜態(tài)成員函數(shù)
static void func1(){
cout << "func1 is called\n";
m_H = 666; // 靜態(tài)成員函數(shù)只能訪問靜態(tài)成員變量
// m_HO = 721; 錯(cuò)誤,不可訪問非靜態(tài)成員變量
}
private:
static int m_L;
static void func2() {
cout << "func2 is called\n";
}
};
// 靜態(tài)成員變量在類外初始化
int Hello::m_H = 100;
int Hello::m_L = 102;
// 靜態(tài)成員變量的訪問方式
void test07() {
// 1.通過對(duì)象
Hello h;
h.m_H = 134;
cout << "h.m_H =" << h.m_H << endl;
Hello h1;
h1.m_H = 999;
// 共享同一份數(shù)據(jù)
cout << "h.m_H =" << h.m_H << endl;
cout << "h1.m_H =" << h1.m_H << endl;
// 2.類名直接訪問
cout << "h.m_H =" << Hello::m_H << endl;
// 靜態(tài)成員函數(shù)的訪問方式
// 1.通過對(duì)象
Hello h2;
h2.func1();
cout << "h2.m_H =" << h2.m_H << endl;
// 2.通過類名
Hello::func1();
// Hello::func2(); 沒有訪問權(quán)限
cout << "Hello::m_H =" << Hello::m_H << endl;
}
// C++中的對(duì)象模型和this指針
// 1.在c++中,類內(nèi)的成員變量和成員函數(shù)分開存儲(chǔ)
// 2.只有非靜態(tài)成員變量才屬于類的對(duì)象上
class Student1{
public:
Student1() {
m_id = 0;
}
// 普通成員函數(shù)也不占用對(duì)象空間,所有函數(shù)共用一個(gè)函數(shù)實(shí)例
void func() {
cout << "m_id = " << this->m_id << endl;
}
// 靜態(tài)成員函數(shù)不占用對(duì)象空間
static void sfunc() {
cout << "TODO\n";
}
private:
// 非靜態(tài)成語(yǔ)變量占用對(duì)象空間
double m_id;
// 靜態(tài)成員變量不占用對(duì)象空間
static int m_tel;
};
// this指針概念:
// cpp中成員變量和成員函數(shù)是分開存儲(chǔ)的----->每個(gè)非靜態(tài)成員函數(shù)只會(huì)產(chǎn)生一份函數(shù)實(shí)例,即多個(gè)同類型的對(duì)象會(huì)共用一塊代碼
// -------->同一塊非靜態(tài)成員函數(shù)代碼如何區(qū)分哪個(gè)對(duì)象調(diào)用自己的?
// cpp通過特殊的對(duì)象指針this解決,this指針指向被調(diào)用的成員函數(shù)所屬的對(duì)象
// this指針是隱含每一個(gè)非靜態(tài)成員函數(shù)內(nèi)的一種指針;
// this指針用途:當(dāng)形參和成員變量同名時(shí),可以用this指針來區(qū)分;在類的非靜態(tài)成員函數(shù)中返回對(duì)象本身return *this
class Teacher{
public:
Teacher(int age) {
// 1.當(dāng)形參和成員變量同名時(shí),用this指針來區(qū)分
this->age = age;
}
Teacher(const Teacher& t) {
cout << "teacher copy constructor\n";
}
Teacher& TeacherAddTeacher(Teacher t){ // 會(huì)調(diào)用拷貝構(gòu)造函數(shù)
this->age += t.age;
// 2.返回對(duì)象本身
return *this;
}
int age;
};
// 空指針訪問成員函數(shù)
// cpp中空指針也是可以訪問成員函數(shù)的,注意有沒有用到this指針,如果用到則需要加判斷來保證代碼的健壯性
class Player{
public:
void showClassName(){
cout << "Class Player\n";
}
void showPlayer(){
if(this == nullptr) return;
cout << mAge << endl;
}
public:
int mAge;
};
void test11() {
Player* p = nullptr;
p->showClassName(); // 空指針,可以調(diào)用成員函數(shù)
p->showPlayer(); // 但是如果成員函數(shù)中用到了this指針,就不可以了
}
// const修飾成員函數(shù)
// 常函數(shù):
// 成員函數(shù)后加const后這個(gè)函數(shù)稱為常函數(shù)
// 常函數(shù)內(nèi)部不可以修改成員屬性
// 成員屬性聲明時(shí)加關(guān)鍵字mutable時(shí),在常函數(shù)內(nèi)部依然可以修改
// 常對(duì)象:
// 聲明對(duì)象前加const稱此對(duì)象是常對(duì)象
// 常對(duì)象只能調(diào)用常函數(shù)
class Const{
public:
Const(){
m_A = 0;
m_B = 0;
}
// this指針的本質(zhì)是一個(gè)指針常量,指針的指向不可以改變
// 如果希望指針指向的值也不可以修改,需要聲明為常函數(shù)
void showConst() const {
// const修飾成員函數(shù),表示指針指向的內(nèi)存空間的數(shù)據(jù)不能被修改,除了mutable修飾的變量
this->m_B = 100;
}
void MyFunc() const {
// m_A = 100;
}
public:
int m_A;
mutable int m_B;
};
void test22() {
const Const cs; // 常對(duì)象cs
cout << cs.m_A << endl;
// cs.mA = 100; 常對(duì)象不能修改成員變量的值,但可以訪問
cs.m_B = 1000;
cs.MyFunc(); // 常對(duì)象只能訪問常成員函數(shù)
}
int main() {
// Circle c(2); 顯式
// Circle c = 10; 隱式
Circle c(10);
cout << "ZC is: " << c.calculateZC() << endl;\
Student stu("zhangsan", 18, 1120001);
stu.showStudentInfo();
// stu.m_name; 類外不可以訪問
// stu.m_aa; 類外可以訪問
// 構(gòu)造函數(shù)的分類及調(diào)用
Person p; // 調(diào)用無參構(gòu)造函數(shù)
Person p1(10); // 括號(hào)法 顯示法
Person p2 = 20; // 隱式轉(zhuǎn)換法
Person p3 = Person(18);
Person p4 = p2; // 調(diào)用拷貝構(gòu)造函數(shù)
test02();
test03();
cout << "--------test04---------\n";
test04();
cout << "--------Test---------\n";
test05();
cout << "--------test06---------\n";
test06();
cout << "--------test07---------\n";
test07();
cout << "--------test08---------\n";
cout << "sizeof(Student1) = " << sizeof(Student1) << endl;
cout << "--------test09---------\n";
Student1 s1;
s1.func();
cout << "--------test10---------\n";
Teacher t1(24);
cout << "t1.age = " << t1.age << endl;
cout << "-----split line---------\n";
Teacher t2(35);
t2.TeacherAddTeacher(t1).TeacherAddTeacher(t1).TeacherAddTeacher(t1);
cout << "t2.age = " << t2.age << endl;
cout << "--------test11---------\n";
test11();
cout << "--------test22---------\n";
test22();
return 0;
}
C++基礎(chǔ)復(fù)習(xí)3
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 一、模板 關(guān)鍵詞:template <typename T>使用方式:1、定義模板 2、使用模板 模板的目的是為了...
- 每年總會(huì)安排時(shí)間進(jìn)行基礎(chǔ)復(fù)習(xí),這次關(guān)注的是c語(yǔ)言數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)及c++設(shè)計(jì)模式。 將c語(yǔ)言采用了面向?qū)ο蟮脑O(shè)計(jì)方法,...
- 正在快速熟悉語(yǔ)法中... 因?yàn)樾枰謴?fù)手感,所以干脆就拿著譚浩強(qiáng)書籍開始第一步,然后在快速進(jìn)入狀態(tài).等語(yǔ)法差不多了...
- 注意事項(xiàng) 對(duì)于不帶.h的頭文件,所有的符號(hào)都位于命名空間 std 中,使用時(shí)需要聲明命名空間 std;對(duì)于帶.h的...