2012-04-11 43 views
11

Sử dụng trường hợp:Tại sao không có khái niệm "const-correctness" cho các hàm thành viên tĩnh của lớp?

class A { 
    static int s_common; 
public: 
    static int getCommon() const { s_common; }; 
}; 

Thông thường điều này dẫn đến một lỗi như:

error: static member function ‘static int A::getCommon()’ cannot have cv-qualifier

Điều này là do const Ness chỉ áp dụng cho các đối tượng được trỏ bởi this, mà không phải là hiện diện trong một hàm static thành viên .

Tuy nhiên, nó đã được cho phép, hàm "const" của hàm thành viên static có thể dễ dàng liên quan đến các thành viên dữ liệu static.
Tại sao tính năng này không có trong C++; bất kỳ lý do logic đằng sau nó?

+1

@keety, [câu hỏi đó] (http://stackoverflow.com/questions/7035356/c-why-static-member-function-cant-be-created-with-const-qualifier) ​​có liên quan và không trùng lặp , Tôi đã thấy điều đó và upvoted nó. Đối số con trỏ 'this' tôi đã đề cập trong câu hỏi của tôi và nó dường như không đủ. – iammilind

+0

mát mẻ nhưng có thể tốt hơn nếu bạn liên kết chuỗi gốc trong câu hỏi để có được ngữ cảnh hoặc tâm trí bạn kết thúc với cùng một câu trả lời – keety

Trả lời

6

cv-qualifiers ảnh hưởng đến chữ ký của hàm. Vì vậy, bạn có thể có:

class A { 
    static int s_common; 
public: 
    static void getCommon() const { }; 
    static void getCommon() { }; 
}; 

Bây giờ ... làm cách nào bạn gọi số const? Không có đối tượng const để gọi nó (tốt, bạn có thể gọi nó trên một đối tượng const, nhưng đó không phải là vấn đề).

Tôi chỉ đoán ở đây, có thể có nhiều lý do khác. :)

+3

Sự kết hợp như vậy có thể được coi là bất hợp pháp. Tôi không chắc đó là lý do đủ tốt để loại trừ khả năng đó. –

+2

@MichaelAnderson tại sao nó sẽ là bất hợp pháp? Tiêu chuẩn cho biết bạn có thể quá tải bởi cv-qualifiers. Bất cứ điều gì có thể được coi là bất hợp pháp nếu chúng ta thay đổi các quy tắc đủ. –

+0

-1 @Luchian: các quy tắc mới sẽ cho phép 'static const' sẽ phải làm cho quá tải không hợp lệ, vì nó không thể dễ dàng được giải quyết ngoại trừ bằng cách đúc. đó là lý do tại sao. vì vậy tôi nghĩ rằng câu trả lời của bạn đã được chọn không chính xác như một giải pháp: nó không phải là một lý do gì cả, chỉ là một quan niệm sai lầm liên quan. –

1

Đoán của tôi là sử dụng staticconst trên chức năng thành viên để tham chiếu đến constness của các biến thành viên tĩnh đơn giản không bao giờ được coi là một tùy chọn. IMO đề xuất của bạn là một cách lạ (nhưng có thể hợp lý) để trộn lẫn hai từ khóa đó.

5

Lý do vì có const cv-vòng loại trên hàm thành viên là:
Để chỉ ra rằng con trỏ ẩn this được truyền cho hàm thành viên là không thay đổi và nó không thể được sửa đổi. Hàm thành viên static không có tham số this ẩn và do đó const cho static chức năng thành viên là vô nghĩa.

Tuy nhiên, nó đã được cho phép, hàm "const" của hàm thành viên tĩnh có thể dễ dàng liên quan đến các thành viên dữ liệu tĩnh.

Đó không phải là lý do để có vòng loại const để bắt đầu, đây là điều hiển nhiên từ thực tế là bạn không thể có vòng loại cv áp dụng cho chức năng miễn phí. Các cv-qualifiers được và chỉ có nghĩa là cho this, đối tượng có chức năng đang được gọi.

+0

Tôi cũng đã xóa nhận xét của tôi vì nó không có ý nghĩa gì nếu không có bình luận trước đó của bạn. Tôi cảm thấy một vòng lặp vô hạn sắp tới. :)) –

+0

Thú vị, tôi chỉ đơn giản nghĩ đến 'const' như một cách để nói hàm sẽ không thay đổi đối tượng. Điều đó có nghĩa là nó thừa cho một chức năng tĩnh (vì nó * có * không có đối tượng) nhưng tôi không thể thấy tại sao nó sẽ * không được phép * thay vì chỉ bị bỏ qua. – paxdiablo

1

Câu hỏi hay.

Tôi tin rằng khái niệm const-ness áp dụng cho đối tượng được xác định rõ hoặc cấu trúc dữ liệu. Không phải toàn cầu/tĩnh hoặc v.v.

Cũng giống như cách tôi có thể hỏi tại sao chức năng toàn cầu (hoặc không gian tên cụ thể) có thể không là const, tức là nó có thể hứa sẽ không sửa đổi bất kỳ biến toàn cầu (hoặc không gian tên cụ thể) .

Điều này không làm cho IMHO có ý nghĩa quá nhiều. Nhưng có, const-ness của các thành viên tĩnh thuộc về một lớp cụ thể - có thể hữu ích trong một số trường hợp IMHO.

8

However had it been allowed, the static member function's "const"ness could have been easily related to the static data members.

Đây là câu hỏi của bạn bị nhầm lẫn. Hàm thành viên không tĩnh được khai báo là const vẫn có quyền truy cập không const tới static thành viên dữ liệu. const chỉ áp dụng cho this (ví dụ: các thành viên dữ liệu không tĩnh). Sẽ không có ý nghĩa gì đối với chức năng thành viên tĩnh sử dụng const theo cách tương tự như cú pháp, nhưng có kết quả hoàn toàn khác (ví dụ: truy cập vào các thành viên dữ liệu tĩnh const).

Hơn nữa, các thành viên dữ liệu tĩnh không có gì khác hơn các biến toàn cục có phạm vi lớp có các điều khiển truy cập lớp (công khai/riêng tư/v.v) trên chúng. Vì vậy, nó không có ý nghĩa đối với một số chức năng để có quyền truy cập khác nhau const cho họ, đặc biệt là dựa trên chữ ký của họ.

2

Chức năng không thay đổi mọi trạng thái toàn cầu là tinh khiết. C++ 11 giới thiệu các thuộc tính có thể bao gồm [[pure]] trên các nền tảng cụ thể.

Một vấn đề với const là một phần của loại loại của hàm. Chỉ định hàm static const cho con trỏ hàm "bình thường" sẽ yêu cầu quy tắc chuyển đổi, truyền hoặc phân tách đặc biệt. Và như Luchian đề cập, nó sẽ cho phép quá tải hoàn toàn mơ hồ.

Về cơ bản, bạn mô tả việc tạo thành một đối tượng đơn lẻ từ các thành viên static, chia sẻ đường dẫn truy cập gián tiếp, đủ điều kiện chung. Đối với đối tượng không phải const xuất hiện const, nó phải được truy cập thông qua một cái gì đó, nhưng không có this. decltype có thay đổi không? Không có câu trả lời hay. Nếu bạn muốn tất cả điều này, sau đó đặt chúng một cách rõ ràng bên trong một đối tượng class.

+0

Đó là một điểm tốt. [[Pure]] có phải là tiện ích mở rộng không? Tôi thường tham khảo [wiki link for C++ 11] (http: //en.wikipedia.org/wiki/C% 2B% 2B11), nhưng không thể tìm thấy bằng grep đơn giản. – iammilind

+0

@iammilind '[[pure]]' không phải là tiêu chuẩn, và tôi không cho rằng bất kỳ nền tảng nào thực hiện nó. Nhưng GCC có '__attribute __ ((thuần))' và MSVC có thứ gì đó tương tự, IIRC. Các thuộc tính gây tranh cãi và có thể có một sự tẩy chay giữa các triển khai chính (xem bài viết gần đây của Herb Sutter) vì vậy những thứ như '[[pure]]' có thể không bao giờ được di chuyển. – Potatoswatter

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