2010-01-08 147 views
3

我寫了下面的程序來測試時,拷貝構造函數被調用,當賦值運算符稱爲:拷貝構造函數和賦值運算符

 

#include 

class Test 
{ 
public: 
    Test() : 
     iItem (0) 
    { 
     std::cout << "This is the default ctor" << std::endl; 
    } 

    Test (const Test& t) : 
     iItem (t.iItem) 

    { 
     std::cout << "This is the copy ctor" << std::endl; 
    } 

    ~Test() 
    { 
     std::cout << "This is the dtor" << std::endl; 
    } 

    const Test& operator=(const Test& t) 
    { 
     iItem = t.iItem;  
     std::cout << "This is the assignment operator" << std::endl; 
     return *this; 
    } 

private: 
    int iItem; 
}; 

int main() 
{ 
    { 
     Test t1; 
     Test t2 = t1; 
    } 
    { 
     Test t1; 
     Test t2 (t1); 
    } 
    { 
     Test t1; 
     Test t2; 
     t2 = t1; 
    } 
} 

這將導致下面的輸出(剛剛添加empy線,使其更容易理解):

 
[email protected]:~$ ./test 
This is the default ctor 
This is the copy ctor 
This is the dtor 
This is the dtor 

This is the default ctor 
This is the copy ctor 
This is the dtor 
This is the dtor 

This is the default ctor 
This is the default ctor 
This is the assignment operator 
This is the dtor 
This is the dtor 


如預期的第二組和第三組的行爲,但在第一組複製CONSTRU即使使用賦值運算符,也會調用ctor。

是C++標準,或只是一個聰明的編譯器優化(我用gcc 4.4.1)

回答

10

沒有賦值運算符是在第一次測試案例中使用的這種行爲的一部分。它只是使用稱爲「複製初始化」的初始化表單。初始化對象時,複製初始化不考慮顯式構造函數。

struct A { 
    A(); 

    // explicit copy constructor 
    explicit A(A const&); 

    // explicit constructor 
    explicit A(int); 

    // non-explicit "converting" constructor 
    A(char const*c); 
}; 

A a; 
A b = a; // fail 
A b1(a); // succeeds, "direct initialization" 

A c = 1; // fail, no converting constructor found 
A d(1); // succeeds 

A e = "hello"; // succeeds, converting constructor used 

複印初始化將在對應於隱式轉換,其中,一個沒有明確踢掉轉換,如在函數參數傳遞的那些情況下使用,並且從函數返回。

2

你的第一套是根據C++標準,而不是由於一些優化。

C++ standard的12.8節([class.copy])給出了一個類似的例子:

class X { 
    // ... 
public: 
    X(int); 
    X(const X&, int = 1); 
}; 

X a(1);  // calls X(int); 
X b(a, 0); // calls X(const X&, int); 
X c = b; // calls X(const X&, int); 

最後一行將是一個符合你的情況。

3

C++標準的8.5/12

的發生在 元傳遞,函數返回初始化, 拋出異常(15.1),處理 異常(15.3),和 括號包圍的初始化列表 (8.5.1)被稱爲複製初始化 和相當於形式

T x = a; 

發生在新的初始化 式(5.3.4),的static_cast 式(5.2.9),功能 符號類型轉換(5.2.3),和 基和成員初始化(12.6.2) 稱爲直接初始化和相當於 表格

T x(a); 
相關問題