類的定義
6. 類定義的語(yǔ)法格式
- 在定義數(shù)據(jù)成員時(shí)不能直接進(jìn)行初始化级野,要為數(shù)據(jù)成員提供初始值應(yīng)該放在構(gòu)造函數(shù)中。
- 類定義的末尾應(yīng)添加分號(hào)颓哮。
7. C++ 中類成員訪問權(quán)限有哪幾種袭异,簡(jiǎn)述其作用对省?
- private:類中的 private 成員只能夠在本類中或者友元類中進(jìn)行訪問。子
類或者外界是無(wú)法訪問私有成員的口渔。 - protected:類中的 protected 成員只允許本類或者子類中進(jìn)行訪問样屠。外界
無(wú)法訪問 protected 成員。在定義類時(shí)缺脉,如果希望該成員能夠被子類繼承痪欲,但是不被外界訪問,可以定義 protected 成員攻礼。 - public:類中的 public 成員能夠在本類业踢、子類和外界中都能夠進(jìn)行訪問。
通常礁扮,類中向用戶提供的服務(wù)設(shè)計(jì)為 public 成員知举。
8. 如何在類中定義常量成員并為其初始化?
要為常量初始化太伊,需要在類的構(gòu)造函數(shù)的初始化部分進(jìn)行雇锡,也就是在構(gòu)
造函數(shù)的函數(shù)體前使用 “:” 定義初始化區(qū)域,在該區(qū)域進(jìn)行初始化僚焦。
class CBook
{
public:
const double m_Price; //定義常量成員
CBook() :m_Price(89.8) //為常量進(jìn)行初始化
{
}
};
9. 由析構(gòu)函數(shù)引起的遞歸調(diào)用
析構(gòu)函數(shù)由系統(tǒng)自動(dòng)調(diào)用锰提。有兩種情況將導(dǎo)致析構(gòu)函數(shù)被調(diào)用。一是對(duì)
象的作用域消失芳悲,二是使用 delete 運(yùn)算符釋放對(duì)象立肘。
class CNode
{
public:
CNode* pNext;
CNode() //構(gòu)造函數(shù)
{
pNext = this;
}
~CNode() //析構(gòu)函數(shù)
{
if(pNext!=NULL)
{
delete pNext;
pNext = NULL;
}
}
};
上面代碼出現(xiàn)了遞歸調(diào)用。在析構(gòu)函數(shù)中執(zhí)行 “delete pNext;” 語(yǔ)句時(shí)導(dǎo)致遞歸芭概。因?yàn)樵谖鰳?gòu)函數(shù)中使用 delete 運(yùn)算符釋放自身赛不,這將導(dǎo)致再次調(diào)用析構(gòu)函數(shù)惩嘉,致使析構(gòu)函數(shù)出現(xiàn)遞歸罢洲。
10. 在 C++ 中如何定義內(nèi)聯(lián)成員函數(shù)
- 在定義成員函數(shù)時(shí)使用inline 關(guān)鍵字。
class CBook
{
private:
double m_Price;
public:
inline void SetPrice(double Price); //使用 inline 關(guān)鍵字定義內(nèi)聯(lián)函數(shù)
CBook()
{
}
};
void CBook::SetPrice(double Price)
{
m_Price = Price;
}
- 在定義成員函數(shù)時(shí)直接寫出函數(shù)體文黎。
class CBook
{
private:
double m_Price;
public:
void SetPrice(double Price) //在定義成員函數(shù)時(shí)直接給出函數(shù)體惹苗,自動(dòng)為內(nèi)聯(lián)函數(shù)
{
m_Price = Price;
}
CBook()
{
}
};
11. 構(gòu)造函數(shù)與普通函數(shù)在形式上有何不同?
- 名字與類相同耸峭,無(wú)返回值
- 無(wú)參數(shù)桩蓉,或若干參數(shù),無(wú)參數(shù)的構(gòu)造函數(shù)叫默認(rèn)構(gòu)造函數(shù)劳闹;如果不提供構(gòu)造函數(shù)院究,則編譯器提供默認(rèn)構(gòu)造函數(shù)洽瞬,如提供了任何形式的構(gòu)造函數(shù),編譯器不會(huì)提供默認(rèn)構(gòu)造函數(shù)
12. 如何定義兩個(gè)類互為成員的情況业汰?
classA
{
private:
B m_B;
};
class B
{
private:
Am_A;
};
不用進(jìn)行編譯伙窃,就可以預(yù)知存在錯(cuò)誤。因?yàn)樵陬?A 之前样漆,沒有發(fā)現(xiàn)類 B 的定義为障,直接使用了類 B。為了解決這個(gè)矛盾放祟,需要在類 A 上方前導(dǎo)聲明類 B鳍怨。但是這還不能完全解決問題。因?yàn)榍皩?dǎo)聲明只是聲明一個(gè)類跪妥,而沒有類的定義鞋喇,編譯器在編譯類 A 時(shí)需要實(shí)例化類 B,但是卻沒有發(fā)現(xiàn)類 B 的定義骗奖,而只是發(fā)現(xiàn)了類 B 的聲明确徙。解決方式是在類 A 中,將 m_B 對(duì)象修改為指針類型执桌。
class B; //前導(dǎo)聲明類 B
classA
{
private:
B *m_B; //定義類 B 的指針類型
};
class B
{
private:
Am_A;
};
13. 已知 String 類的定義鄙皇, 請(qǐng)?zhí)砑訉?shí)現(xiàn)部分。
class String
{
public:
String(const char *str = NULL); //通用構(gòu)造函數(shù)
String(const String &another); //拷貝構(gòu)造函數(shù)
~ String(); //析構(gòu)函數(shù)
String &operator =(const String &rhs); //賦值函數(shù)
private:
char *m_data; //用于保存字符串
};
在定義一個(gè)類時(shí)如果沒有指定這些函數(shù)仰挣,編譯器會(huì)為其提供這 4 個(gè)特殊的函數(shù)伴逸。除了構(gòu)造函數(shù)之外,其余 3 個(gè)函數(shù)都具有特定的函數(shù)原型膘壶。例如错蝴,析構(gòu)函數(shù)的名稱為 “~” 加上類名,沒有參數(shù)和返回值颓芭∏昝蹋拷貝構(gòu)造函數(shù)與類名相同,參數(shù)為一個(gè)常量引用類型參數(shù)亡问。賦值函數(shù)參數(shù)為常量引用類型官紫,返回值為類引用類型。
構(gòu)造函數(shù)用于創(chuàng)建類對(duì)象州藕。析構(gòu)函數(shù)用于釋放對(duì)象束世。拷貝構(gòu)造函數(shù)用于
在類對(duì)象作為函數(shù)參數(shù)或函數(shù)返回值時(shí)被調(diào)用床玻,用于臨時(shí)構(gòu)建對(duì)象毁涉。賦值函數(shù)用于實(shí)現(xiàn)對(duì)象間的直接賦值。
參考代碼如下:
String::String(const char *str) //實(shí)現(xiàn)構(gòu)造函數(shù)
{
if ( str == NULL ) //判斷參數(shù)是否為空
{
m_data = new char[1] ;
m_data[0] = '\0' ;
}
else
{
m_data = new char[strlen(str) + 1];
strcpy(m_data, str);
}
}
String::String(const String &another) //實(shí)現(xiàn)拷貝構(gòu)造函數(shù)
{
m_data = new char[strlen(another.m_data) + 1];
strcpy(m_data, another.m_data);
}
String& String::operator =(const String &rhs) //實(shí)現(xiàn)賦值函數(shù)
{
if ( this == &rhs)
return *this ;
delete []m_data; //刪除原來(lái)的數(shù)據(jù)锈死,新開一塊內(nèi)存
m_data = new char[strlen(rhs.m_data) + 1];
strcpy(m_data,rhs.m_data);
return *this ;
}
String::~String() //實(shí)現(xiàn)析構(gòu)函數(shù)
{
delete []m_data ;
}
14. 在定義類的成員函數(shù)時(shí)使用 mutable 關(guān)鍵字的作用是什么?
在定義類的方法時(shí)贫堰,如果在方法的末尾使用 const 關(guān)鍵字穆壕,表示該方法為 const 方法,此時(shí)在方法中不允許修改對(duì)象的信息其屏。例如粱檀,下面的代碼將出現(xiàn)編譯錯(cuò)誤。
class CStudent
{
private:
intAge;
int Weight;
public:
void SetAge(intAge);
int GetAge()const; //定義 const 方法
};
void CStudent::SetAge(intAge)
{
this->Age =Age; //通過 this 指針來(lái)訪問成員 Age
}
int CStudent::GetAge()const
{
Weight = 10; //此處將出現(xiàn)編譯錯(cuò)誤
returnAge;
}
上述代碼在 const 方法中修改 Weight 成員導(dǎo)致的語(yǔ)法錯(cuò)誤漫玄。為了能夠在 const 方法中修改對(duì)象的成員信息茄蚯,可以在成員前使用 mutable 關(guān)鍵字。例如睦优,下面的代碼是完全合法的渗常。
class CStudent
{
private:
intAge;
mutable int Weight;
public:
void SetAge(intAge);
int GetAge() const ;
};
void CStudent::SetAge(intAge)
{
this->Age =Age; //通過 this 指針來(lái)訪問成員 Age
}
int CStudent::GetAge() const //實(shí)現(xiàn) const 方法
{
Weight = 10; //在 const 方法中為數(shù)據(jù)成員賦值
return Age;
}
當(dāng)需要在 const 方法中修改對(duì)象的數(shù)據(jù)成員時(shí),可以在數(shù)據(jù)成員前使用 mutable 關(guān)鍵字汗盘,防止出現(xiàn)編譯錯(cuò)誤皱碘。
參考資料:
C++繼承權(quán)限和繼承方式