2011-05-10 25 views
13

thể trùng lặp:
Why isn't the const qualifier working on pointer members on const objects?Tại sao C++ không thực thi const trên dữ liệu con trỏ?

Hãy xem xét các lớp sau đó có một thành viên con trỏ int *a. Phương thức const constMod được trình biên dịch cho phép mặc dù nó sửa đổi dữ liệu con trỏ. Tại sao trình biên dịch không làm cho dữ liệu con trỏ const trong ngữ cảnh của phương thức const? Nếu a chỉ là một int chúng tôi sẽ không được phép sửa đổi nó trong một phương pháp const.

class ConstTest 
{ 
    public: 

    ConstTest(int *p): a(p) {} 

    void constMod() const { 
     ++(*a); 
    } 

    int *a; 
}; 

Tôi đang sử dụng g + + trên Linux.

+0

câu trả lời duy nhất là "bởi vì nó như thế này", nhưng tôi nghĩ rằng hầu hết chúng ta đồng ý nó thường bất ngờ (lúc đầu), mặc dù người ta có thể tìm ra lý do sau đó. –

+0

C++ theo mặc định cung cấp một cái gọi là bit constness - có nghĩa là nó đảm bảo rằng không có bit của đối tượng đã được thay đổi, vì vậy nó chỉ kiểm tra địa chỉ của con trỏ – rank1

Trả lời

4

Nó chỉ là vấn đề quyền sở hữu ... không có cách nào trình biên dịch có thể biết nếu đối tượng được trỏ tới là một phần của đối tượng hay không, vì vậy nó được để lại cho lập trình viên. const thành viên được phép thực hiện các thao tác với các hiệu ứng phụ, miễn là chúng không sửa đổi giá trị rõ ràng của chúng. Nó không thực sự khác với việc cho phép họ gọi là std::cout::operator<<() hoặc một số chức năng khác không phải là ...

13

Bên constMod(), việc kê khai a được xử lý như sau:

int *const a; 

có nghĩa là con trỏ có một giá trị không đổi, không phải những gì nó điểm để. Có vẻ như bạn đang mong đợi nó được coi là:

const int *a; 

khác biệt.

+1

Có phải không làm rõ câu hỏi mà không trả lời nó ...? –

+0

Vậy tại sao lại như vậy? Tại sao không thực thi const tất cả mọi thứ trong một phương pháp const? Có vẻ lạ khi xử lý dữ liệu con trỏ như là một tác dụng phụ. – MattSmith

+0

@Matt: Đó chỉ là cách C++. Hãy tưởng tượng nó là một số nguyên thay vì một con trỏ, và bạn không thể thay đổi số nguyên. Số nguyên đó có ý nghĩa gì đối với * bạn * không có gì liên quan đến giá trị của nó. Tương tự như vậy, giá trị con trỏ không có gì liên quan đến những gì nó chỉ ra (chúng ta chỉ đồng ý rằng giá trị con trỏ chỉ ra một địa chỉ, tất cả thời gian, thay vì những thứ khác nhau như một số nguyên có thể, nhưng tương tự vẫn giữ). Đối với những gì nó có giá trị, ngôn ngữ D hoạt động như bạn mong đợi. – GManNickG

7

Bản thân con trỏ không bị sửa đổi, chỉ dữ liệu được trỏ. Ngay cả khi nó có vẻ kỳ lạ từ quan điểm của con người, từ quan điểm của trình biên dịch, không ai trong số các thành viên của lớp bị thay đổi.

0

Trường hợp trên là chính con trỏ . Bạn không được phép làm ++a;. Tuy nhiên, nó không ngăn bạn sửa đổi dữ liệu được trỏ đến.

0

Tôi tin rằng vì ở đây bạn đang cố thay đổi giá trị mà dữ liệu đang trỏ đến. Nếu bạn cố sửa đổi thành viên dữ liệu, đó sẽ là lỗi.

Ý nghĩa, bạn sẽ nhận được báo lỗi nếu bạn thực hiện một điểm đến cái gì khác thay vì thay đổi các giá trị chức năng

0

const thành viên sẽ không cho phép bạn sửa đổi nó là thành viên.

Trong ví dụ của bạn, bạn có một con trỏ chỉ một int.

Và trong phương thức const, bạn đang sửa đổi giá trị mà nó được trỏ đến nhưng không phải chính con trỏ.

Hãy thử tặng, ++a, điều này sẽ thực sự sửa đổi giá trị con trỏ và sẽ không được phép trong phương thức const của bạn.

0

Cân nhắc

const T immutable_object0; 
const T immutable_object1; 
const T* mutable_view = ...a condition... ? &immutable_object0 : &immutable_object1; 
// then later you reseat 
mutable_view = ...another condition... ? &immutable_object0 : &immutable_object1; 

hoặc

const int immutable_data[120] 
const int* mutable_view = immutable_data; 
for(const int* end = immutable_data + 120; mutable_view != end; ++mutable_view) { 
    // can't modify *mutable_view 
} 

Đó là bởi vì con trỏ không phải lúc nào có quyền sở hữu. Trong một số trường hợp con trỏ là các khung nhìn đối tượng (ví dụ đầu tiên) hoặc là các trình vòng lặp vào một mảng thô (ví dụ thứ hai). Đối với những trường hợp đó không có ý nghĩa để hạn chế các hoạt động có sẵn trên con trỏ chỉ vì dữ liệu được trỏ đến là không thay đổi (hoặc được xem là không thay đổi).

Ví dụ đầu tiên có chút sai lệch nhưng phiên bản hợp lệ của nó là khi bạn sử dụng thành viên con trỏ để triển khai liên kết đối tượng và bạn không muốn gặp rắc rối của thành viên tham chiếu. Đôi khi các loại được chỉ định xảy ra là const.

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