2009-04-01 33 views
5

Tôi đã có mã C++ sau đây, trong đó đối số cho hàm dựng của tôi trong khai báo có độ chói khác với định nghĩa của hàm tạo.Không khớp giữa định nghĩa hàm tạo và khai báo

//testClass.hpp 
class testClass { 
    public: 
    testClass(const int *x); 
}; 

//testClass.cpp 
testClass::testClass(const int * const x) {} 

Tôi đã có thể biên dịch điều này mà không có cảnh báo bằng cách sử dụng g ++, mã này có nên biên dịch hoặc ít nhất là đưa ra một số cảnh báo không? Nó chỉ ra rằng trình biên dịch C++ tích hợp trên Solaris 64 bit đã cho tôi một lỗi liên kết, đó là cách tôi nhận thấy rằng có một vấn đề.

Quy tắc đối sánh đối sánh trong trường hợp này là gì? Là nó lên đến trình biên dịch?

Trả lời

7

Trong trường hợp như thế này, trình định danh const được phép là ommitt ed từ tuyên bố vì nó không thay đổi bất cứ điều gì cho người gọi.

Chỉ quan trọng đối với ngữ cảnh của chi tiết triển khai. Vì vậy, đó là lý do tại sao trên định nghĩa nhưng không phải là khai báo .

Ví dụ:

//Both f and g have the same signature 
void f(int x); 
void g(const int x); 

void f(const int x)//this is allowed 
{ 
} 

void g(const int x) 
{ 
} 

Bất cứ ai gọi e sẽ không quan tâm rằng bạn sẽ đối xử với nó như const vì nó là bản sao của riêng bạn của biến.

Với int * const x, nó giống nhau, đó là bản sao con trỏ của bạn. Cho dù bạn có thể trỏ đến điều gì khác không quan trọng với người gọi.

Nếu bạn đã bỏ mặc const đầu tiên mặc dù trong const int * const, thì điều đó sẽ tạo sự khác biệt bởi vì nó quan trọng với người gọi nếu bạn thay đổi dữ liệu mà nó trỏ đến.

tham khảo: C++ chuẩn, 8.3.5 para 3:

"Bất cứ cv-vòng loại thay đổi một loại tham số này sẽ bị xóa ... Chẳng hạn cv-vòng loại chỉ ảnh hưởng đến định nghĩa của tham số với nội dung của hàm; chúng không ảnh hưởng đến loại chức năng "

+0

Vui lòng cung cấp tham chiếu đến Tiêu chuẩn. –

+0

Tôi đã viết về nó ở đây, nếu bạn cần thêm ví dụ: http://stackoverflow.com/questions/269882/c-const-question/274888#274888 –

+0

@ onebyone.livejournal.com: Cảm ơn. –

4

nghĩ về nó như sự khác biệt giống nhau giữa

//testClass.hpp 
class testClass { 
    public: 
    testClass(const int x); 
}; 

//testClass.cpp 
testClass::testClass(int x) {} 

nào cũng biên dịch. Bạn không thể quá tải dựa trên const-ness của một tham số pass-by-value. Hãy tưởng tượng trường hợp này:

void f(int x) { } 
void f(const int x) { } // Can't compile both of these. 

int main() 
{ 
    f(7); // Which gets called? 
} 

Từ tiêu chuẩn:

tờ khai Parameter rằng khác chỉ trong sự hiện diện hay vắng mặt của const và/hoặc không ổn định là tương đương. Đó là, const và biến động loại-specifiers cho mỗi tham số loại được bỏ qua khi xác định mà chức năng đang được tuyên bố, xác định, hoặc gọi. [Ví dụ:

typedef const int cInt; 
int f (int); 
int f (const int); // redeclaration of f(int) 
int f (int) { ... } // definition of f(int) 
int f (cInt) { ... } // error: redefinition of f(int) 

-end dụ] Chỉ có const và dễ bay hơi kiểu specifiers tại mức ngoài cùng của các loại tham số đặc điểm kỹ thuật được bỏ qua trong thời trang này; const và dễ bay hơi type-specifiers chôn trong một kiểu đặc tả tham số là đáng kể và có thể được sử dụng để phân biệt quá tải chức năng declarations.112) Đặc biệt, cho bất kỳ loại T, “con trỏ đến T,” “con trỏ đến const T”và‘con trỏ đến dễ bay hơi T’được xem là khác biệt loại tham số, như là‘tài liệu tham khảo để T’,‘tham chiếu đến const T’, và ‘tham chiếu đến T. dễ bay hơi’

0

const int * const x không giống như const int * x bởi vì bạn đã maked const?

+0

No. Trong trường hợp đầu tiên, x là một con trỏ const đến một số nguyên const. Trong trường hợp thứ hai, x là một con trỏ * non-const * đến một số nguyên const. –

+0

Cụ thể, ngay từ đầu bạn có thể sửa đổi cả x và x. Trong trường hợp thứ hai, bạn không thể sửa đổi x *, nhưng bạn có thể sửa đổi x. Ví dụ, thứ hai có thể được sử dụng để đi qua một mảng (với x ++, ví dụ), và thứ hai không thể. –

5

Ví dụ này được bao phủ một cách rõ ràng trong phần giải quyết tình trạng quá tải, 13.1/3b4:

tờ khai Parameter mà chỉ khác nhau ở sự hiện diện hay vắng mặt của const và/hoặc dễ bay hơi là tương đương. Nghĩa là, const và các kiểu biến dạng dễ bay hơi cho mỗi kiểu tham số được bỏ qua khi xác định hàm nào đang được khai báo, xác định hoặc gọi.

[Ví dụ:

typedef const int cInt; 
int f (int); 
int f (const int); // redeclaration of f(int) 
int f (int) { ... } // definition of f(int) 
int f (cInt) { ... } // error: redefinition of f(int) 

-end dụ]

Vì vậy, nó chắc chắn là OK.

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