鍍金池/ 問答/C++/ C++構(gòu)造問題求解

C++構(gòu)造問題求解

class A{
private:
    double re, im;
public:
    A(){}
    A(double r, double i) : re{r}, im{i} {}
    double real() { return re; }
};

int main(){
    A a(1, 2);
    A c(a);            // 這一句
    cout << c.real();
    
    A d();
    cout << d.real();    // error: request for member 'real' in 'd', which is of non-class type 'A()'
    A e{};
    cout << e.real();    // 隨機的一個 double 數(shù)
 }

為什么我沒有定義用一個對象去初始化另一個對象的構(gòu)造器, A c(a) 還是可以呢?

另外,想問一下 () 和 {} 有什么區(qū)別呢?
{} 用來初始化,() 就是用來傳參嘛?
為什么 d 和 e 行為不一樣呢?

回答
編輯回答
貓小柒
  1. A c(a) 會調(diào)用 A::A(const A&),是 A 的拷貝構(gòu)造函數(shù),它與控構(gòu)造函數(shù)一樣,如果不自定義,編譯器會自動生成一個。
  2. 使用花括號來初始化對象是 C++11 的標準:

    1. 花括號調(diào)用構(gòu)造器會傾向于使用初始化列表構(gòu)造,被構(gòu)造會按照列表被填充;被構(gòu)造對象也可以選擇用 std::initializer_list 來捕獲這個列表。
      http://zh.cppreference.com/w/...
      例一,基本類型可以直接填充:int a{10}
      例二,std::array 是一個結(jié)構(gòu)體,內(nèi)部是原生數(shù)組,也可以自動填充:std::array<int, 3> f3{1, 2, 3};。
      例三,std::vector 實現(xiàn)了 std::initializer_list 構(gòu)造:std::vector<int> v{10, 3}(得到長 2 的 vector,v[0] 是 10,v[1] 是 3)。
    2. 在上述情況匹配失敗的時候,不會得到編譯錯誤,而是會嘗試匹配類的構(gòu)造器,例如:std::vector<std::string> v{10, "hello"},會得到長度是 10 的 vector。因為與上面的例三對比,它匹配 vector(std::initializer_list<T>, const Allocator& alloc = Allocator()) 失敗了。
      http://zh.cppreference.com/w/...
    3. C++ 中 A a() 的作用往往出人意料,它不是用空參數(shù)構(gòu)造器構(gòu)造一個 A 類型的對象,而是聲明一個返回類型是 A,函數(shù)名是 a,并且函數(shù)參數(shù)列表空的函數(shù);期待的空參數(shù)構(gòu)造方式應(yīng)該是 A a。11 標準選取了 A a{},其作用與 A a 無異。
2017年2月11日 07:22
編輯回答
壞脾滊

A(a)是拷貝構(gòu)造函數(shù),你沒有定義編譯器會給你自動生成一個。

至于{}、()的區(qū)別,就是小括號會調(diào)用默認初始化器初始化,而大括號不會。

2017年2月5日 21:43