免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
C++類成員的初始化

1、關(guān)于構(gòu)造函數(shù)

1)用構(gòu)造函數(shù)確保初始化

對(duì)于一個(gè)空類

class Empty { };
編譯器會(huì)自動(dòng)聲明4個(gè)默認(rèn)函數(shù):構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),賦值函數(shù),析構(gòu)函數(shù)(當(dāng)然,如果不想使用自動(dòng)生成的函數(shù),就應(yīng)該明確拒絕),這些生成的函數(shù)都是public且inline。構(gòu)造函數(shù)對(duì)數(shù)據(jù)成員進(jìn)行初始化,使用未初始化值可能導(dǎo)致無法預(yù)知的錯(cuò)誤,所以,確保每一個(gè)構(gòu)造函數(shù)都將每一個(gè)成員初始化。

2)為什么構(gòu)造函數(shù)不能有返回值

如果有返回值,要么編譯器必須知道怎么處理返回值,要么就客戶程序員顯式調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù),這樣,還有安全性么?

3)為什么構(gòu)造函數(shù)不能為虛函數(shù)

簡單來說,虛函數(shù)調(diào)用的機(jī)制,是知道接口而不知道其準(zhǔn)確對(duì)象類型的函數(shù),但是創(chuàng)建一個(gè)對(duì)象,必須知道對(duì)象的準(zhǔn)確類型;當(dāng)一個(gè)構(gòu)造函數(shù)被調(diào)用時(shí),它做的首要事情之一就是初始化它的VPTR來指向VTABLE。

4)構(gòu)造函數(shù)的一個(gè)面試題:
#include <iostream>
using namespace std;
class Base
{
private:
 int i;
public:
 Base(int x)
 {
  i = x;
 }
};
class Derived : public Base
{
private:
 int i;
public:
 Derived(int x, int y)
 {
  i = x;
 }
 void print()
 {
  cout << i + Base::i << endl;
 }
};
int main()
{
 Derived A(2,3);
 A.print();
    return 0;
}
首先,是訪問權(quán)限問題,子類中直接訪問Base::i是不允許的,應(yīng)該將父類的改為protected或者public(最好用protected)

其次,統(tǒng)計(jì)父類和子類i的和,但是通過子類構(gòu)造函數(shù)沒有對(duì)父類變量進(jìn)行初始化;此處編譯會(huì)找不到構(gòu)造函數(shù),因?yàn)樽宇愓{(diào)用構(gòu)造函數(shù)會(huì)先找父類構(gòu)造函數(shù),但是沒有2個(gè)參數(shù)的,所以可以在初始化列表中調(diào)用父類構(gòu)造函數(shù)

最后個(gè)問題,是單參數(shù)的構(gòu)造函數(shù),可能存在隱式轉(zhuǎn)換的問題,因?yàn)閱螀?shù)構(gòu)造函數(shù),和拷貝構(gòu)造函數(shù)形式類似,調(diào)用時(shí)很可能會(huì)發(fā)生隱式轉(zhuǎn)換,應(yīng)加上explicit關(guān)鍵字,修改后如下
#include <iostream>
using namespace std;
class Base
{
protected:
 int i;
public:
 explicit Base(int x)
 {
  i = x;
 }
};
class Derived : public Base
{
private:
 int i;
public:
 Derived(int x, int y):Base(x)
 {
  i = y;
 }
 void print()
 {
  cout << i + Base::i << endl;
 }
};
int main()
{
 Derived A(2,3);
 A.print();
    return 0;
}

2、初始化列表

1)使用初始化列表提高效率

常用的初始化可能如下:
class Student
{
public:
 Student(string in_name, int in_age)
 {
  name = in_name;
  age = in_age;
 }
private :
 string name;
 int    age;
};
這么寫,可以達(dá)到預(yù)期效果,不過不是最佳做法,因?yàn)樵跇?gòu)造函數(shù)中,是對(duì)name進(jìn)行賦值,不是初始化,而string對(duì)象會(huì)先調(diào)用它的默認(rèn)構(gòu)造函數(shù),再調(diào)用string類(貌似是basic_string類)的賦值構(gòu)造函數(shù);對(duì)于上例的age,因?yàn)閕nt是內(nèi)置類型,應(yīng)該是賦值的時(shí)候獲得了初值。

    要對(duì)成員進(jìn)行初始化,而不是賦值,可以采用初始化列表(member initialization list)改寫為如下:
class Student
{
public:
 Student(string in_name, int in_age):name(in_name),age(in_age) {}
private :
 string name;
 int    age;
};
 結(jié)果與上例相同,不過在初始化的時(shí)候調(diào)用的是string的拷貝構(gòu)造函數(shù),而上例會(huì)調(diào)用兩次構(gòu)造函數(shù),從性能上會(huì)有不小提升

    有的情況下,是必須使用初始化列表進(jìn)行初始化的:const對(duì)象、引用對(duì)象

2)初始化列表初始順序

考慮以下代碼:
#include <iostream>
using namespace std;
class Base
{
public:
 Base(int i) : m_j(i), m_i(m_j) {}
 Base() : m_j(0), m_i(m_j) {}
 int get_i() const
 {
  return m_i;
 }
 int get_j() const
 {
  return m_j;
 }
private:
 int m_i;
 int m_j;
};
int main()
{
 Base obj(98);
 cout << obj.get_i() << endl << obj.get_j() << endl;
    return 0;
}
輸出為一個(gè)隨機(jī)數(shù)和98,為什么呢?因?yàn)閷?duì)于初始化列表而言,對(duì)成員變量的初始化,是嚴(yán)格按照聲明次序,而不是在初始化列表中的順序進(jìn)行初始化,如果改為賦值初始化則不會(huì)出現(xiàn)這個(gè)問題,當(dāng)然,為了使用初始化列表,還是嚴(yán)格注意聲明順序吧,比如先聲明數(shù)組大小,再聲明數(shù)組這樣。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C#函數(shù)(構(gòu)造函數(shù))的重載
Java的無參構(gòu)造函數(shù)
C 析構(gòu)函數(shù)
C++之繼承基礎(chǔ)
java 必須用this的幾種情況
轉(zhuǎn):C#中base關(guān)鍵字的幾種用法
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服