2012-02-26 4 views
11

thể trùng lặp:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?Tại sao hàm tạo không được gọi khi() được sử dụng để khai báo một đối tượng?

$ cat cons.cpp 
#include <iostream> 

class Matrix { 
private: 
    int m_count; 

public: 
    Matrix() { 
     m_count = 1; 
     std::cout << "yahoo!" << std::endl; 
    } 
}; 

int main() { 
    std::cout << "before" << std::endl; 
    Matrix m1();       // <---- 
    std::cout << "after" << std::endl; 
} 
$ g++ cons.cpp 
$ ./a.out 
before 
after 
$ 

không cú pháp Matrix m1(); làm gì?

Tôi tin rằng nó giống như Matrix m1;. Rõ ràng tôi sai.

Trả lời

12
Matrix m1(); // m1 is a function whose return type is Matrix. 

Đồng thời, câu hỏi thường gặp này sẽ hữu ích.

Is there any difference between List x; and List x();

+1

@Lazer: để thuyết phục chính mình, cố gắng sử dụng m1 (ví dụ truy cập m1.m_count) ... – Francesco

+0

Trong C++ 11 bạn có thể sử dụng niềng răng đối với tất cả các hàm gọi hàm dựng, điều này tránh được sự phân tích cú pháp khó hiểu nhất của C++, tức là ma trận m1 {}; – mark

+0

Đây không phải là "phân tích cú pháp khó chịu nhất", phân tích cú pháp gây tranh cãi nhất là khi bạn cố gắng khai báo và đối tượng và chuyển một giá trị được khởi tạo tạm thời cho một hoặc nhiều tham số hàm tạo. Ví dụ. 'A b (A());'. 'Matrix m1();' chỉ là một khai báo hàm thông thường. –

3

Matrix m1() tuyên bố một hàm mang theo không có tham số và trả về một Matrix. Bạn có thể thấy điều này rất bằng cách thêm một phương pháp để Matrix và cố gắng để gọi nó trên m1:

#include <iostream> 

class Matrix { 
private: 
    int m_count; 

public: 
    Matrix() { 
     m_count = 1; 
     std::cout << "yahoo!" << std::endl; 
    } 
    void foo() {} 
}; 

int main() { 
    std::cout << "before" << std::endl; 
    Matrix m1(); 
    m1.foo(); 
    std::cout << "after" << std::endl; 
} 

cho error: request for member 'foo' in 'm1', which is of non-class type 'Matrix()'

0

này sẽ làm những gì bạn đang cố gắng để làm:

int main() { 
    std::cout << "before" << std::endl; 
    Matrix m1;       // <---- 
    std::cout << "after" << std::endl; 
} 

Trong C++, nếu bạn khởi tạo một biến với parens, nó thực sự khai báo một hàm không có tham số và trả về kiểu đó.

1

suy nghĩ từ góc độ ngôn ngữ C:

int data_member(); 

thực sự là một nguyên mẫu cho chức năng chụp khoảng trống và trở int. Khi bạn thay đổi nó như:

T data(); 

nó vẫn là khai báo hàm, retuning T. Khi bạn cần phải khai báo nó như biến, bạn làm:

T data; // int data;