2016-10-19 244 views
-1

假設我有一個類,如下所示:構造方法對象作爲參數

class A{ 
    int x ; 
    A(int i){ 
     x = i ; 
    } 
} 

我有具有作爲成員對象類A的一個實例,另一類B.

class B{ 
    int y ; 
    A obj_a ; 
    B(int j , A a){ 
     y = j ; 
     obj_a = a ; 
    } 
} 

當我做到以下幾點:

int main(){ 
     A obj1(1) ; // obj.x has value 1 
     B obj2(2 , obj1) ; 
    } 

第二行拋出一個錯誤說形式的無函數調用:: A()。我知道這意味着缺少一個默認樣式構造函數,但爲什麼我需要這個呢? obj1是使用定義的構造函數創建的,因此不是問題。

我目前的想法是A aobj_a = a會調用隱式定義的複製構造函數。

注意:爲簡潔起見,我已排除私人,公共等。

+1

後實際的錯誤。你的ctor可能抱怨它應該是'const int i'; – stark

+1

您明確要求不使用初始化程序列表。 – kfsone

回答

1

的對象必須是完全一致的,其所有成員的構成,由一次進入構造函數的主體。因此,在

B(int j , A a){ 
    y = j ; 
    obj_a = a ; 
} 

{ 
    y = j ; 
    obj_a = a ; 
} 

都有機會做任何事情,obj_a必須已經建立。

由於對如何構建obj_a沒有該命令而提供的Member Initializer Listobj_a將與A類的默認構造函數來構建。類A沒有默認的構造函數,沒有A::A(),所以引發錯誤。

解決方法是使用成員初始化程序列表,而不是在函數體內賦值。這不僅可以幫助您構建一個會立即被覆蓋的對象,編譯器還可以通過更多的途徑來優化,並且您可能會進行一些其他小改進。

B應該是:

class B{ 
    int y ; 
    A obj_a ; 
    B(int j , A a): y(j), obj_a(a) 
    { 
    } 
} 
+0

是在這裏創建的對象'a'的值嗎?是否可以通過參考傳遞? –

+0

@AbhinavVishak'a'目前按值傳遞,可能需要一個副本。是的,你可以通過引用傳遞「a」。 – user4581301

3

obj_a = a調用operator=,而不是複製構造函數。事情是,obj_a使用默認構造函數進行初始化,因爲您尚未指定在初始化程序列表中調用哪個構造函數。

B(int j , A a) /*: obj_a{}*/ { /*...*/ } 
       ^^^^^^^^^^^^^ 
      implicit call to default constructor 

你必須顯式調用構造函數的成員初始化列表中的一個論點:

B(int j , A a) : obj_a{ a } { /*...*/ } 
+0

那麼這個問題與'obj_a = a'沒有多大關係。它是參數列表中的'A a'。我如何解決這個問題? –

+1

@AbhinavVishak'a **在參數列表中不是問題。問題是mem-initialiser列表中缺少'obj_a'(':'後面的列表)。 – Angew

+0

@agnew我做了你建議的更改,然後編譯。謝謝 !我仍然對初始化列表的使用感到困惑,請仔細閱讀一下。我假設在使用':obj_a {a}'後,我不需要'obj_a = a'? –

相關問題