久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C++類成員的初始化

 sun317 2013-03-04

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

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

對于一個空類

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

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

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

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

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

4)構(gòu)造函數(shù)的一個面試題:
#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)計父類和子類i的和,,但是通過子類構(gòu)造函數(shù)沒有對父類變量進(jìn)行初始化;此處編譯會找不到構(gòu)造函數(shù),,因為子類調(diào)用構(gòu)造函數(shù)會先找父類構(gòu)造函數(shù),,但是沒有2個參數(shù)的,所以可以在初始化列表中調(diào)用父類構(gòu)造函數(shù)

最后個問題,,是單參數(shù)的構(gòu)造函數(shù),,可能存在隱式轉(zhuǎn)換的問題,,因為單參數(shù)構(gòu)造函數(shù),和拷貝構(gòu)造函數(shù)形式類似,,調(diào)用時很可能會發(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ù)期效果,不過不是最佳做法,,因為在構(gòu)造函數(shù)中,,是對name進(jìn)行賦值,不是初始化,,而string對象會先調(diào)用它的默認(rèn)構(gòu)造函數(shù),,再調(diào)用string類(貌似是basic_string類)的賦值構(gòu)造函數(shù);對于上例的age,,因為int是內(nèi)置類型,,應(yīng)該是賦值的時候獲得了初值。

    要對成員進(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é)果與上例相同,不過在初始化的時候調(diào)用的是string的拷貝構(gòu)造函數(shù),,而上例會調(diào)用兩次構(gòu)造函數(shù),,從性能上會有不小提升

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

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;
}
輸出為一個隨機(jī)數(shù)和98,,為什么呢?因為對于初始化列表而言,,對成員變量的初始化,,是嚴(yán)格按照聲明次序,而不是在初始化列表中的順序進(jìn)行初始化,,如果改為賦值初始化則不會出現(xiàn)這個問題,,當(dāng)然,為了使用初始化列表,,還是嚴(yán)格注意聲明順序吧,,比如先聲明數(shù)組大小,再聲明數(shù)組這樣,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多