effective C++筆記之條款26:當心潛在的二義性

三種可能的情況

1.類中構造函數與重載轉換運算符間的二義性,如下所示:

class B;
class A
{
public:
	A(const B& b) {  cout << "A()" << endl; }
private:
	int data;
};

class B
{
public:
	B():data(0) {}
	operator A() const;
private:
	int data;
};
void ff(const A& a)
{
	cout << "ff" << endl;
}

int main()
{
	B b;
	ff(b);  //錯誤,會產生二義性
	system("pause");
	return 0;
}

產生二義性的原因是因爲有兩種方法來實現由B轉換爲A,一種方法是調用類A的構造函數,另一種是調用類B裏自定義的轉換運算符。這兩個途徑都一樣可行,所以編譯器拒絕從他們中選擇一個。

2.  函數調用中也存在二義性

void ff(int a)
{
	cout << "ff(int)" << endl;
}

void ff(char a)
{
	cout << "ff(char)" << endl;
}

int main()
{
	double a = 10.0;
	ff(a); //錯誤。二義性。要想調用,需ff(static_cast<int>(a));
	return 0;
}

該函數調用的二義性來源於C++語言的標準轉換。a轉換成int和char都可以,所以編譯器不會通過。


3.多繼承中存在的二義性

class Base1
{
public:
	void dolt(void) { cout << "Base1::dolt()" << endl; }
};

class Base2
{
public:
	void dolt(void) { cout << "Base2::dolt()" << endl; }
};

class Derived : public Base1, public Base2
{
	
};

int main()
{
	Derived a;
a.dolt(); //錯誤,二義性。要想成功調用,需指明函數所在的基類,如//a.Base1::dolt();
return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章