日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

c++类指针赋值表达式必须是可修改的左值_C++进阶教程系列:全面理解C++中的类...

發(fā)布時間:2024/10/6 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++类指针赋值表达式必须是可修改的左值_C++进阶教程系列:全面理解C++中的类... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原標題:C++進階教程系列:全面理解C++中的類

關(guān)注Linux公社

最近刷了一些題,也面試了一些公司,把關(guān)于C++中關(guān)于類的一些概念總結(jié)了一下。

在這里也反思一下,面試前信心滿滿自以為什么都懂,毫無準備就大膽得去了,然后就覺得自己臉都被打腫了。回來認認真真刷題,這陣子都不敢再去面試了~~。

1. 類的訪問屬性:public,protect,private

C++中類的成員變量和函數(shù)都帶有三種屬性中的一種,假如沒有特別聲明,那么就默認是私有的(除了構(gòu)造函數(shù))。public表示是公開的,對象可以直接調(diào)用的變量或者函數(shù);protect表示是保護性的,只有本類和子類函數(shù)能夠訪問(注意只是訪問,本類對象和子類對象都不可以直接調(diào)用),而私有變量和函數(shù)是只有在本類中能夠訪問(有個例外就是友元函數(shù),這個后面會詳細說)。

classA

{

public:

A( intb):m_public(b),m_protected( 1), m_private( 2){}

intm_public;

protected:

intm_protected;

private:

intm_private;

};

intmain( void)

{

A a( 10);

cout<<<<endl; //正確,可以直接調(diào)用

cout<<a.m_protected<<endl; //錯誤,不可以直接調(diào)用

cout<<a.m_private<<endl; //錯誤,不可能直接調(diào)用

}

而子類對父類的繼承類型也有這三種屬性,分別為公開繼承,保護繼承和私有繼承。

classA

{

public:

A( intb):m_public(b),m_protected( 1), m_private( 2){}

intm_public;

protected:

intm_protected;

private:

intm_private;

};

classB: publicA{} //公有繼承

classC: protectedA{} //保護繼承

classD: privateA{} //私有繼承

于是問題來了,父類成員的公開屬性有三種,子類的繼承屬性也有同樣的三種,那么一共就有九種搭配(例如公開繼承父類公開成員,私有繼承父類公開成員,保護繼承父類私有成員等等)。

我們只需要記住這 兩個里取嚴格的那一種。例如私有繼承父類公開成員,那么在子類里父類的所有屬性都變成子類私有的了。

具體如下所示:

public: protected: private:

public繼承 public protected 不可用

protected繼承 protected protected 不可用

private繼承 private private 不可用

classA

{

public:

A( intb):m_public(b){}

intm_public;

};

classB: privateA

{

public:

B( intnum):A(num){}

};

intmain

{

B b( 10);

cout<<b.m_public<<endl; //錯誤,無法直接調(diào)用私有成員

}

2. 類的四個默認函數(shù):構(gòu)造,拷貝構(gòu)造,賦值,析構(gòu)(這一點要背下來,面試直接被問了)

  • 每當構(gòu)建一個新的類,編譯器都會給每個類生成以上四個默認的無參構(gòu)造函數(shù),并且這四個函數(shù)都是默認public的。

classA

{

public:

doublem_a;

};

intmain( void)

{

A a; //調(diào)用默認無參構(gòu)造函數(shù),此時m_a的值是不確定的,不能用

//離開主函數(shù)前調(diào)用析構(gòu)函數(shù),釋放a的內(nèi)存

}

但是一旦程序員自己定了帶參數(shù)的構(gòu)造函數(shù),那么編譯器就 不會再生成默認的無參構(gòu)造函數(shù)了,但是還是有默認的拷貝和賦值構(gòu)造函數(shù)。因此假如只定義了有參數(shù)的構(gòu)造函數(shù),那么這個類就沒有無參構(gòu)造函數(shù)。

classA

{

public:

A( inti):m_a(i){}

intm_a;

};

intmain( void)

{

A a; //錯誤!沒有無參構(gòu)造函數(shù)

A a1( 5); // 調(diào)用了A中程序員定義的有參構(gòu)造函數(shù)

A a2( 6); // 調(diào)用了A中程序員定義的有參構(gòu)造函數(shù)

A a3 = a1; //此處調(diào)用默認的拷貝構(gòu)造函數(shù)

a2 = a1; //此處調(diào)用默認的賦值函數(shù)

}

上面的程序中尤其需要注意的是 A a3 = a1這一句,雖然有等號,但是仍然是拷貝構(gòu)造函數(shù)。拷貝構(gòu)造函數(shù)和賦值函數(shù)的區(qū)別在于等式左邊的對象是否已經(jīng)存在。a2 = a1這一句執(zhí)行的時候,a2已經(jīng)存在,因此是賦值函數(shù),而執(zhí)行A a3 = a1這一句的時候,a3還不存在,因此為拷貝構(gòu)造函數(shù)。

默認的賦值和拷貝構(gòu)造函數(shù)一般只是簡單的拷貝類中成員的值, 這一點當類中存在指針成員和靜態(tài)成員變量的時候就非常危險。例如以下一種情況:

classA

{

public:

A( inti, int* p):m_a(i), m_ptr(p){} intm_a;

int*m_ptr;

};

intmain( void)

{

intm = 10, *p = &m;

A a1( 3, p);

A a2 = a1; //a2 和 a1的m_ptr都指向了同一地址

*p = 100;

cout<<*()<<endl; //輸出為100

}

這也就是C++中由于指針帶來的淺拷貝的問題,只賦值了地址,而沒有新建對象。因此假如類中存在靜態(tài)變量或者指針成員變量時一定要自己手動定義賦值、拷貝構(gòu)造、析構(gòu)函數(shù)。

classA

{

public:

A( intb):m_public(b),m_protected( 1), m_private( 2){}

intm_public;

protected:

intm_protected;

private:

intm_private;

};

intmain( void)

{

A a( 10);

cout<< ""<<endl; //正確,可以直接調(diào)用

cout<<a.m_protected<<endl; //錯誤,不可以直接調(diào)用

cout<<a.m_private<<endl; //錯誤,不可能直接調(diào)用

}

可以理解成不能。子類會繼承父類所有的函數(shù),包括構(gòu)造函數(shù) ,但是子類的構(gòu)造函數(shù)會把父類的構(gòu)造函數(shù)覆蓋了,所以看起來就是沒有繼承。假如子類不定義任何構(gòu)造函數(shù),那么子類只會默認地調(diào)用父類的無參構(gòu)造函數(shù)。當 父類中只定義了有參構(gòu)造函數(shù),從而不存在無參構(gòu)造函數(shù)的話,子類就無法創(chuàng)建對象。

classA

{

public:

A( intb):m_public(b){}

intm_public;

};

classB: publicA

{

};

intmain

{

B b; //出錯,因為父類沒有無參構(gòu)造函數(shù)

}

因此在這種情況必須要顯示定義子類的構(gòu)造函數(shù),并且在子類構(gòu)造函數(shù)中顯示調(diào)用父類的構(gòu)造函數(shù)。

classA

{

public:

A( intb):m_public(b){}

intm_public;

};

classB: publicA

{

public:

B( intnum):A(num){}

};

intmain

{

B b1; //出錯,由于父類沒有無參構(gòu)造函數(shù),因此B也不存在無參構(gòu)造

B b2( 5); //正確

}

  • 構(gòu)造函數(shù)的構(gòu)造順序:先構(gòu)造基類,再構(gòu)造子類中的成員,再構(gòu)造子類
classA

{

public:

A{ cout<< "constructing A"<<endl;}

};

classB

{

public:

B{ cout<< "constructing B"<<endl;}

};

classC: publicA

{

public:

B b;

A a;

intnum;

C( intn):num(n){ cout<< "constructing C"<<endl;}

};

intmain

{

C c( 1);

}

運行結(jié)果為:

第一行的constructingA就是在構(gòu)建基類,然后構(gòu)建b對象,再構(gòu)建a對象,最后構(gòu)建c本身。

而析構(gòu)的順序就正好是完全反過來,先析構(gòu)子類,再析構(gòu)子類中的對象,最后析構(gòu)基類。

  • 假如把構(gòu)造函數(shù)和析構(gòu)函數(shù)定義成私有的會怎樣?(被問的時候真的一臉懵,-_-//)

假如把構(gòu)造函數(shù)定義為私有,那么類就無法 直接實例化(還是可以實例化的,只是要轉(zhuǎn)個彎)。來看下面這個例子:

classA

{

public:

intm_public;

staticA* getInstance( intnum)

{

returnnewA(num);

}

private:

A( intb):m_public(b){}

};

intmain

{

A a1( 4); //錯誤

A* pa = A::getInstance( 5); //正確

}

有些時候,我們不希望一個類被過多地被實例化,比如有關(guān)全局的類、路由類等。這時候,我們就可以用這種方法為類設(shè)置構(gòu)造函數(shù)并提供靜態(tài)方法。

假如把類的析構(gòu)函數(shù)定義為私有,那么就無法在棧中生成對象,而必須要通過new來在堆中生成對象。

另外在這里提及一點,對應(yīng)的,如何讓類只能在棧中生成,而不能new呢?就是將new 和delete重載為私有。

原因是C++是一個靜態(tài)綁定的語言。在編譯過程中,所有的非虛函數(shù)調(diào)用都必須分析完成。即使是虛函數(shù),也需檢查可訪問性。因些,當在棧上生成對象時,對象會自動析構(gòu),也就說析構(gòu)函數(shù)必須可以訪問。而堆上生成對象,由于析構(gòu)時機由程序員控制,所以不一定需要析構(gòu)函數(shù)。

classA

{

public:

intm_public;

staticA* getInstance( intnum)

{

returnnewA(num);

}

A( intb):m_public(b){}

private:

~A{}

};

intmain

{

A a( 5); //錯誤,因為系統(tǒng)無法自動調(diào)用析構(gòu)函數(shù)

A *p_a = newA( 5); //正確,此時p_a指向的是堆中的內(nèi)存

}

  • 構(gòu)造函數(shù)的初始化列表(就是構(gòu)造函數(shù)冒號后面的東西,叫初始化列表,需要與{}中的函數(shù)內(nèi)容區(qū)分開)

有幾種情況必須要使用初始化列表:

常量成員

引用類型

沒有默認構(gòu)造函數(shù)的類類型

classA

{

public:

intm_a;

A( intnum):m_a(num){}

};

classB

{

public:

constintm_const;

int&m_ref;

A a;

B( intnum, intb):m_ref(b), m_const( 1), a(num) //初始化列表

{

cout<< "constructing B"<<endl;

}

};

intmain

{

intn = 5;

B b( 1, n);

}

還需要注意的一點是,初始化列表里的真正賦值的順序其實是 按照成員變量的聲明順序,而不是初始化列表中顯示的順序。例如這里是先初始化m_const,然后是m_ref,最后是a。

來看下面一個例子:

classA

{

public:

intm_a;

A( intnum):m_a(num){ cout<< "constructing A"<<endl;}

};

voidtest(A a)

{

cout<<a.m_a+ 1<<endl;

}

intmain

{

A a1= 6; //此時等式右邊的6隱式生成了一個以6為參數(shù)的A類對象

test( 6); //輸出7,入?yún)⒁搽[式生成了一個以6為參數(shù)的A類對象

cout<<a1.m_a<<endl; //輸出6

}

從下面的運行結(jié)果可以看出,A的構(gòu)造函數(shù)被調(diào)用了兩次。

這種隱式轉(zhuǎn)換有時候神不知鬼不覺,為了避免這種情況,于是有了explicit關(guān)鍵字。當構(gòu)造函數(shù)被聲明為explicit后,就必須要顯式調(diào)用構(gòu)造方法來生成對象了,而無法進行隱式轉(zhuǎn)換。

classA

{

public:

intm_a;

explicitA( intnum):m_a(num){ cout<< "constructing A"<<endl;}

};

voidtest(A a) { cout<<a.m_a+ 1<<endl;

}

intmain

{

A a1= 6; //錯誤

test( 6); //錯誤

}

3. 虛函數(shù)

虛函數(shù)是C++實現(xiàn)多態(tài)的方法。虛函數(shù)和普通函數(shù)沒有什么區(qū)別,只有當用基類指針調(diào)用子類對象的方法時才能夠真正發(fā)揮它的作用,也只有在這種情況下,才能真正體現(xiàn)出C++面對對象編程的多態(tài)性質(zhì)。

先來了解一下綁定的概念。函數(shù)體與函數(shù)調(diào)用關(guān)聯(lián)起來叫做綁定。

  • 早綁定:早綁定發(fā)送在程序運行之前,也是編譯和鏈接階段。
classA

{

public:

intm_a;

A( intnum):m_a(num){}

intadd( intn)

{

returnm_a + n;

}

};

intmain

{

A a( 1);

cout<<( 5);

}

在上面的代碼中,函數(shù)add在編譯期間就已經(jīng)確定了實現(xiàn)。這就是早綁定。所有的非虛函數(shù)都是早綁定。

  • 晚綁定:晚綁定發(fā)生在程序運行期間,主要體現(xiàn)在繼承的多態(tài)方面。

引用一句Bruce Eckel的話:“不要犯傻,如果它不是晚邦定,它就不是多態(tài)。”

classA

{

public:

intm_a;

A( intnum):m_a(num){}

voidvirtualshow

{

cout<< "base function"<<endl;

}

};

classB: publicA

{

public:

B( intn):A(n){}

voidshow

{

cout<< "derived function"<<endl;

}

};

intmain

{

A *pa = newB( 1);

pa->show; //輸出 derived function

}

父類和子類都定義了show方法,在繼承的過程中,由于父類show方法是虛函數(shù),而父類指針指向的是子類對象,所以會在子類對象中去找show函數(shù)的實現(xiàn)。假如子類中沒有show,那么就還是會調(diào)用父類的show。

這個晚綁定的過程是通過虛指針實現(xiàn)的。只要一個類中聲明了有虛函數(shù),那么編譯器就會自動生成一個虛函數(shù)表。雖然名字叫表,但本質(zhì)是一個存放虛函數(shù)指針的函數(shù)指針數(shù)組。一個虛表對應(yīng)一個指針。當該類作為基類,其派生類對基類的(一個或者多個)虛函數(shù)進行重寫時,派生類的虛函數(shù)表中,相應(yīng)的函數(shù)指針的值就會發(fā)生變化。

構(gòu)造函數(shù)不能聲明為虛函數(shù)。虛函數(shù)是晚綁定,一定是先有了基類對象,才會有對應(yīng)的虛指針,再去本類或者子類對象中去找對應(yīng)的實現(xiàn)。所以一定要先通過構(gòu)造函數(shù)創(chuàng)建了對象,才能去實現(xiàn)虛函數(shù)的作用。

而析構(gòu)函數(shù),則常常被聲明為虛函數(shù)。(記得當時面試官問我,析構(gòu)函數(shù)能不能是虛的,我當時斬釘截鐵得回答,不能!-_-//)

先看下面這個例子。

classA

{

public:

intm_a;

A( intnum):m_a(num){ cout<< "constructing A"<<endl;}

~A{ cout<< "destructing A"<<endl;}

};

classB: publicA

{

public:

B( intn):A(n){ cout<< "constructing B"<<endl;}

~B{ cout<< "destructing B"<<endl;}

};

intmain

{

A* pa= newB( 1);

deletepa;

}

執(zhí)行結(jié)果為:

可以看到是先構(gòu)建了A對象,然后構(gòu)建了B對象。可是卻只析構(gòu)了A對象,B對象的內(nèi)存空間就泄漏了。

現(xiàn)在把A的析構(gòu)函數(shù)置為虛函數(shù)的話,

classA

{

public:

intm_a;

A( intnum):m_a(num){ cout<< "constructing A"<<endl;}

virtual~A{ cout<< "destructing A"<<endl;}

};

classB: publicA

{

public:

B( intn):A(n){ cout<< "constructing B"<<endl;}

~B{ cout<< "destructing B"<<endl;}

};

intmain

{

A* pa= newB( 1);

deletepa;

}

運行結(jié)果為:

可以看到這時B對象也被析構(gòu)了。這正是利用了虛函數(shù)晚綁定的特點,當調(diào)用基類指針析構(gòu)函數(shù)的時候,先調(diào)用B的析構(gòu)函數(shù),再調(diào)用A的析構(gòu)函數(shù)。

對于虛函數(shù)始終要注意只有用指針調(diào)用的時候才會有作用,假如只是普通的對象調(diào)用,虛函數(shù)是不起作用的。

classA

{

public:

intm_a;

A( intnum):m_a(num){}

virtualvoidshow

{

cout<< "A::show"<<endl;

}

virtual~A{}

};

classB: publicA

{

public:

B( intn):A(n){}

voidshow

{

cout<< "B::show"<<endl;

}

~B{}

};

intmain

{

A a( 1); a.show; //輸出A::show

B b( 1); //輸出B::show

}

4. 成員函數(shù)的重載、隱藏與覆蓋

(1)相同的范圍(在同一個類中)

(2)函數(shù)名字相同

(3)參數(shù)不同 ,也可以僅僅是順序不同

(4)virtual 關(guān)鍵字可有可無

classA

{

public:

intm_a;

A( intnum):m_a(num){}

voidshow( intn){} //(1)

virtualvoidshow( intn){} //(2) 錯誤!!不是重載,重復定義了(1),因為virtual關(guān)鍵字不能重載函數(shù)

voidshow( doubled){} //(3)show函數(shù)的重載

voidshow( inta, doubleb){} //(4)show函數(shù)的重載

voidshow( doubleb, inta){} //(5)show函數(shù)的重載

voidshow( inta, doubleb) const{} //(6)show函數(shù)的重載,const關(guān)鍵可以作為重載的依據(jù)

voidshow( constinta, doubleb){} //(7)錯誤!!不是重載, 頂層const不可以作為重載的依據(jù),重復定義了(6)

voidshow( int*a){} //(8)show函數(shù)的重載

voidshow( constint*a){} //(9)show函數(shù)的重載,只有底層const才可以作為重載的依據(jù)

voidshow( int* consta){} //(10) 錯誤!!不是重載,重復定義了(8),因為這里也使用了頂層const

};

至于const能不能成為重載的依據(jù)取決于是頂層const還是底層const。頂層const是指對象本身是常量,而底層const是指指向或引用的對象才是常量。

  • 成員函數(shù)的隱藏,這里“隱藏”是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù)

只要子類函數(shù)的名字與基類的相同,那么不管參數(shù)相同與否,都會直接屏蔽基類的同名函數(shù)。

classA

{

public:

voidshow( inta) { cout<< "A::show"<<endl;} //(1)

};

classB: publicA

{

public:

voidshow{ cout<< "B::show"<<endl;} //(2)將(1)屏蔽了

};

  • 假如在子類中仍舊需要用到基類的同名函數(shù),就要用using關(guān)鍵字顯式聲明。
classA

{

public:

voidshow( int) { cout<< "A::show"<<endl;}

};

classB: publicA

{

public:

usingA::show;

voidshow{

show( 0); //一定要在前面顯式聲明using A中的show函數(shù),否則此句會編譯錯誤

cout<< "B::show"<<endl;

}

};

intmain

{

B b;

}

輸出結(jié)果為:

(1)不同的范圍(分別位于派生類與基類)

(2)函數(shù)名字相同

(3)參數(shù)相同

(4) 基類函數(shù)必須有virtual 關(guān)鍵字

這其實就是多態(tài)的實現(xiàn)過程。注意參數(shù)必須要完全一致。之前講過,在此不再贅述。

5. inline關(guān)鍵字

定義在類中的成員函數(shù)默認都是內(nèi)聯(lián)的。內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別在于:當編譯器處理調(diào)用內(nèi)聯(lián)函數(shù)的語句時,不會將該語句編譯成函數(shù)調(diào)用的指令,而是直接將整個函數(shù)體的代碼插人調(diào)用語句處,就像整個函數(shù)體在調(diào)用處被重寫了一遍一樣。這有助于提高程序的運行效率。但是要注意inline函數(shù)僅僅是一個 對編譯器的建議,所以 最后能否真正內(nèi)聯(lián),看編譯器的意思,它如果認為函數(shù)不復雜,能在調(diào)用點展開,就會真正內(nèi)聯(lián),并不是說聲明了內(nèi)聯(lián)就會內(nèi)聯(lián),聲明內(nèi)聯(lián)只是一個建議而已。

這也是為什么虛函數(shù)可以是內(nèi)連函數(shù)。因為僅僅是建議,當虛函數(shù)需要表現(xiàn)出多態(tài)性質(zhì)的時候,編譯器會選擇不內(nèi)連。

6. 友元函數(shù)、友元類

類的友元函數(shù)是定義在類外部,但有權(quán)訪問類的所有私有(private)成員和保護(protected)成員。

classA

{

public:

A( intn):m_a(n){}

friendclassB; //聲明B為A的友元類

private:

intm_a;

};

classB

{

public:

B(A a){ cout<<} //由于B是A的友元類,所以可以直接調(diào)用a的私有m_a成員

};

intmain

{

A a( 1);

B b = B(a); //輸出1

}

要注意盡管友元類很強大,但是友元類和類本身并沒有任何繼承關(guān)系和成員關(guān)系。友元類或友元函數(shù)都不是本類的成員類和成員函數(shù)。

就如名字定義的那樣,只是朋友,不具有任何親屬關(guān)系, 因此無法使用this指針進行調(diào)用

友元函數(shù)常用在重載運算符。因為通常重載運算符的時候都要用到私有變量,所以用友元函數(shù)來重載是非常合適的。

7. 運算符的重載

. (成員訪問運算符)

.*, ->* (成員指針訪問運算符)

:: (域運算符)

sizeof (長度運算符)

?: (條件運算符)

# (預處理符號)

  • =, [] , ,-> 四個符號只能通過成員函數(shù)來重載,不能通過友元函數(shù)來定義

=,->, [], 為什么不能重載為友元函數(shù),是因為當編譯器發(fā)現(xiàn)當類中沒有定義這4個運算符的重載成員函數(shù)時, 就會自己加入默認的運算符重載成員函數(shù)。而如果這四個運算符寫成友元函數(shù)時會報錯,產(chǎn)生矛盾。

  • 不允許用戶定義新的運算符作為重載運算符,不能修改原來運算符的優(yōu)先級和結(jié)合性,不能改變操作對象等等限制

如果是一元操作,就用成員函數(shù)去實現(xiàn)

如果是二元操作,就盡量用友元函數(shù)去實現(xiàn)

如果是二元操作,但是對兩個操作對象的處理不同,那么就盡可能用成員函數(shù)去實現(xiàn)

classA

{

public:

A( intn):m_a(n){}

intm_a;

friendA operator+(A const& a1, A const& a2);

};

A operator+(A const& a1, A const& a2)

{

A res( 0);

res.m_a = 1+ a1.m_a + a2.m_a;

returnres;

}

intmain

{

A a1( 1), a2( 2);

A a3 = a1 + a2;

cout<<a3.m_a; //輸出4

}

8. 再談const關(guān)鍵字

classA

{

public:

A( intn):m_a(n){}

intm_a;

voidshow{ cout<< "A::show"<<endl;}

};

intmain

{

A a1( 1);

constA a2( 2);

a1.show; //正確

a2.show; //錯誤

}

假如增加const函數(shù)后,就可以正常運行。

classA

{

public:

A( intn):m_a(n){}

intm_a;

voidshow{ cout<< "A::show"<<endl;}

voidshow const{ cout<< "A::show const"<<endl;}

};

intmain

{

A a1( 1);

constA a2( 2);

a1.show; //正確 輸出A::show

a2.show; //正確 輸出A::show const,自動調(diào)用const函數(shù)

}

  • A const* 和const A*等價,允許用A* 賦值A(chǔ) const*,但是不允許用A const* 賦值A(chǔ)*
classA

{

public:

A( intn):m_a(n){}

intm_a;

voidchangeValue( int*p){ cout<< "changeValue"<<endl;}

voidchangeValue2( intconst*p){ cout<< "changeValue2"<<endl;}

};

intmain

{

intn = 10;

intconst*p_n_const = &n;

int*p_n = &n;

A a( 1);

(p_n_const); //錯誤,無法把int const*類型,轉(zhuǎn)成int *類型,但是反之可以

2(p_n); //正確,輸出changeValue2

}

這是因為形參const A*表示指向的對象不能改變,所以如果傳入A*實參,只要不改變對象的值就不會有問題。但是如果形參為A*,則有可能改變A*指向的對象,這是const A*辦不到的,所以編譯器不允許傳入const A*作為實參傳入。

暫時總結(jié)到這里。正好最近工作中也寫了不少類的繼承,也實現(xiàn)了一些類的封裝,所以這里也包含了我踩過的一些坑。

參考:

https://github.com/huihut/interview

https://blog.csdn.net/cb673335723/article/details/81231974

合作聯(lián)系微信:linuxg返回搜狐,查看更多

責任編輯:

總結(jié)

以上是生活随笔為你收集整理的c++类指针赋值表达式必须是可修改的左值_C++进阶教程系列:全面理解C++中的类...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。