2013-09-24 17 views
7

Tôi có Simpletron.cpp mà là một trống tập tin, một Simpletron.h mà khai báo một lớp Simpletron:Không thực hiện trong C++ nhưng vẫn có thể gọi nó là

class Simpletron 
{  
public: 
    Simpletron(); 
}; 

tôi gọi Simpletron() trong main.cpp tôi:

#include <iostream> 
#include "Simpletron.h" 

int main(int argc, char *argv[]) 
{ 

    Simpletron s(); 
    std::cin.get(); 
} 

Chức năng chính chỉ chạy trơn tru mà không có bất kỳ cảnh báo hoặc lỗi nào. Tại sao vậy? Làm thế nào mà thậm chí biên dịch nếu không có inplementation tập tin tiêu đề có thể liên kết đến?

+4

@ Smac89: Không phải khi bạn khai báo. Có lẽ tôi sẽ phát điên, nhưng ít nhất 7 người khác cũng sai. Chương trình này sẽ gây ra lỗi liên kết, [ví dụ] (http://ideone.com/5m0ygK). – GManNickG

+0

@octef: Vui lòng cung cấp mã và dòng lệnh thực của bạn. Ví dụ: định nghĩa lớp của bạn thiếu dấu chấm phẩy sau khi nó không thể là mã bạn đang biên dịch. – GManNickG

+0

Chắc chắn, chờ một phút. – octref

Trả lời

24

dòng này:

Simpletron s(); 

là một nguyên mẫu hàm, khai báo một hàm có tên s, trả lại một Simpletron và dùng không có đối số. Nó không tạo ra một cá thể Simpletron có tên là s.

Bây giờ bạn có thể hỏi, tại sao người liên kết không phàn nàn về hàm không tồn tại s() thay thế? Vâng, kể từ khi bạn chỉ tuyên bố s() nhưng không bao giờ thực sự gọi nó, nó không thực sự tham chiếu bất cứ nơi nào trong quá trình liên kết, vì vậy bạn sẽ không có lỗi liên kết.

13
Simpletron s(); 

Đây là tuyên bố chức năng, không phải là đối tượng khởi tạo. Dấu ngoặc rỗng nói với trình biên dịch hàm này không có đối số và trả về một đối tượng kiểu Simpletron theo giá trị, do đó không có hàm tạo nào được gọi. Cú pháp đúng là không có tham số:

Simpletron s; // You will get an error on this line, as initially expected 

C++ 11 bổ sung thêm một tính năng cú pháp mà tránh sự nhập nhằng này:

Simpletron s{}; // same as default-initialization 
+0

Trường hợp "sửa lỗi" có nghĩa là gây ra lỗi liên kết thời gian. –

+0

Nó sẽ không sửa chữa nó. Nó sẽ là một lỗi. – MahanGM

+4

@MahanGM: Nơi "sửa lỗi" có nghĩa là làm cho mã _ hoạt động như mong đợi_. –

5
Simpletron s(); 

Đây là một trường hợp điển hình của việc "phân tích cú pháp gây nhiều tranh cãi"; đối với trình biên dịch, bạn không tạo biến số s của loại Simpletron, nhưng bạn đang khai báo hàm có tên s, không tham số và trả về đối tượng Simpletron.

Điều này xuất phát từ thực tế là biểu thức này có thể được hiểu là cả khai báo hàm và khai báo biến; kể từ khi khai báo biến có một sự thay thế dễ dàng (cụ thể là, chỉ cần bỏ qua các dấu ngoặc đơn) các nhiệm vụ tiêu chuẩn để diễn giải điều này như là một khai báo hàm.

Quá trình biên dịch không cần phải có định nghĩa của tất cả các phương thức, chỉ cần khai báo) và có thể trình liên kết không đưa ra bất kỳ lỗi nào vì không có trường hợp Simpletron thực sự được tạo ra, vì vậy nó không bao giờ cần tìm kiếm định nghĩa hàm tạo (mặc dù tôi không nghĩ rằng đó là đảm bảo không cung cấp lỗi, một trình biên dịch/liên kết đặc biệt toàn diện sẽ có thể cung cấp cho bạn lỗi dù sao).

Các vấn đề liên quan