2012-05-29 60 views
7

行A b(3)產生歧義,因爲它可以調用兩個可能的構造函數中的任何一個。單參數參數化構造函數或具有默認參數的雙參數參數化構造函數。我如何解決這個問題?如何處理默認構造函數和重載構造函數之間的歧義?

#include<iostream> 
using namespace std; 
class A 
{ 
    public: 
    int a,b; 
    A() 
    { 
     a=5; 
     b=6; 
    } 
    A(int a1) 
    { 
     a=a1; 
     b=54; 
    } 
    A(int a1,int b2=8) 
    { 
     a=a1; 
     b=b2; 
    } 
    void show() 
    { 
     cout<<"a="<<a<<" b="<<b<<endl; 
    } 
};  
int main() 
{ 
    A a(3); // I want A(int a1,int b2=8) to get executed 
    A b(3); // I want A(int a1) to get executed 
    a.show(); 
    b.show(); 
    return 0; 
} 
+0

避免這樣的事情開始,你有兩個構造函數調用看起來相同,但產生不同的對象。 –

+0

其中之一是,如果沒有參數,則分配'b' 54,而在另一個分配中,則是在完全相同的情況下分配8。那是什麼?我認爲這是XY問題的一個例子。如果出於某種原因需要此行爲,則存在更高級別的問題。 – chris

+0

有沒有辦法解決這個歧義,所以它調用我們想要它的構造函數? – Ashwyn

回答

5

首先,回答這個問題:

當你寫A a(4),你想a.b.是:

選項A)

class A 
{ 
    public: 
    int a,b; 
    A() 
    { 
     a=5; 
     b=6; 
    } 
    A(int a1,int b2 = 54) 
    { 
     a=a1; 
     b=b2; 
    } 
};  

選項B)

class A 
{ 
    public: 
    int a,b; 
    A() 
    { 
     a=5; 
     b=6; 
    } 
    A(int a1,int b2 = 8) 
    { 
     a=a1; 
     b=b2; 
    } 
};  

的錯誤是有原因的。 如果你不知道你想從代碼中得到什麼,你怎麼期待編譯器呢?

編輯:在你編輯 - 不可能。沒有那個確切的代碼。

+0

這是這個問題的唯一真正的解決方案。這背後的邏輯是非常有缺陷的。源自相同的代碼有兩種不同的行爲。 – chris

1

你從編譯器中要求的含義是模糊的。

A(int a1) 
{ 
    a=a1; 
    b=54; 
} 

A(int a1,int b2=8) 
{ 
    a=a1; 
    b=b2; 
} 

是當你的類獲取只有一個參數創建的相同。首先寫下你自己英語課的期望。然後,將其轉換爲C++代碼。例如:「如果我的類A只用一個參數創建,比讓我的變量等於該參數並讓我的變量b爲54.如果它是由兩個參數創建的,而不是第一個給a,第二個b」和你這個表情代碼:

A(int a1,int b2=54) 
{ 
    a=a1; 
    b=b2; 
} 
0

在你的例子中,編譯器沒有辦法告訴編譯器是否僅僅用一個參數來調用它時,是指第二​​個還是第三個構造器。

通常,如果您需要添加具有其他默認參數的新構造函數,您可以使默認值與前面的構造函數具有相同的行爲並擺脫早期版本,例如,在這種情況下,b2的默認值必須是54.或者,不要給新的構造函數一個默認參數,而只需要調用者明確地傳遞它。

我想另一種選擇是使用默認構造函數將不同參數傳遞給基類構造函數的多個派生類。

class A 
{ 
public: 
    int a, b; 
    A() { a = 5; b = 6; } 
    A(int a1) { a = a1; b = 54; } 
    A(int a1, int b1) { a = a1; b = b1; } 
    ... 
}; 

class B: public A 
{ 
public: 
    B(int a1): A(a1, 8) { } 
}; 

希望A :: b初始化爲8而不是54的代碼會創建一個B代替。但在許多情況下這不是一個好的選擇。

1

刪除A(int a1)功能和代替A b(3)呼叫A b(3, 54)

0

我除去在構造默認= 8和它修復它。您可以在構造函數的實現中指定54,但不能指定參數。否則,它會將其與其他構造函數混淆,而不是= 8參數。