程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Effective C++ 26,27,28

Effective C++ 26,27,28

編輯:C++入門知識

Effective C++ 26,27,28


26.當心潛在的二義性。

一些潛在的二義性的例子:

class A{
public:
	A(const B&);
};
class B{
public:
	operator A() const;
};
void f(const A&);
一般情況下,這樣寫不會出錯,但當調用f函數傳入一個 B的對象b時,就會發生二義性錯誤,b既可以通過A的構造函數獲得一個A的對象,也可以通過B的類型轉換運算符來將b變成一個A的對象再使用,而編譯器不知道應該使用哪種方法。這是一個潛在的二義性,其一般情況下正常無誤。

還有更簡單一點的二義性,當兩個函數重載時,如 f(int ) f(char);,而傳入一個double類型的參數d時,就會發生二義性,編譯器不知道應該將d轉換為char類型還是int類型。

多繼承中充滿了二義性的可能。如多個基類具有同名的函數或數據成員,就必須指明成員的基類來消除二義性,即使一些成員在其所在的基類中是私有的,即派生類無法訪問,但這還是有二義性的錯誤。為什麼消除 對類成員的引用產生的二義性時不考慮訪問權限:改變類成員的訪問權限不應該改變程序的含義,即當類定義好之後,改變成員的訪問屬性會導致一些訪問出錯或這依舊正常,這是正確的,而如果改變訪問屬性改變了程序的含義(如A 類B類派生 出C類,c中一個函數調用兩個基類中同名的成員,如果 消除二義性時考慮了訪問權限, 當A中成員為公有,b中成員為私有時,c中函數調用a中成員,而改變了訪問權限,a中為私有,b中為共有,就會導致c中函數調用b中成員,改變了程序的含義,但是對於程序猿,卻一無所知。如果保護考慮的話,會出現訪問出錯,會提示程序員進行修改) 所以最好還是顯示的消除二義性。


27.如果不想使用隱式生成的函數就要顯式的禁止它。

對於這些不想使用的函數禁止它,原因很簡單,為了之後更容易更新和維護,當你現在在寫這個類時,你沒有禁止這些不應該使用的函數,你記得這些事情,所以你自己不會犯這些錯誤,但當過了很長一段時間,或者其他人接替了你的工作來對你的代碼進行升級和維護時,這個沒有禁止的功能就很有可能出現在一些地方讓你措手不及。所以最好還是禁止這些不應該使用的函數。

對於類中一些函數,編譯器會隱式的自動生成,如缺省的無參構造函數,賦值 =,復制構造函數等,要禁止這些函數,一個簡單的方法就是聲明這些函數為private ,顯示聲明防止編譯器自動生成,而private防止其他人調用。

但這樣還是不安全,成員函數和 友元函數還是可以調用這些私有函數。這樣就只去聲明這些函數,而不去定義函數體,當其他函數調用時,編譯器就會在鏈接時報錯。


28.劃分全局名字空間。

使用命名空間來解決命名沖突。對命名空間之前有過一些研究:c++命名空間,命名空間是可以嵌套的。

命名空間的使用方式有三種, using namespace xxx;之後所有的xxx命名空間的成員都可以直接訪問。 using xxx::成員 ,對於xxx命名空間中的這個成員可以直接使用。xxx::成員,在一個地方使用xxx命名空間中的這個成員。

可以使用struct來近似實現namespace , 先創建一個結構用以保存全局符號名,然後將這些全局符號名作為靜態成員放入結構中。訪問時加上struct的名作為前綴 ,與命名空間類似。

struct sdm{
	static const double VERSION ;
	class A{
	public:
		void  f(){cout<<"SDM"<對於類型名,可以顯式地去掉空間引用:

typedef sdm::A A;
對於函數,一般返回一個函數的常指針:

	sdm::A& (* const getA)()= sdm::getA;
	sdm::A& (& getA)() = sdm::getA;//返回函數的引用



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved