2012-01-09 37 views
26

Mã đi đầu tiên:Hàm const thành viên có thể trả về một con trỏ không const cho một thành viên dữ liệu không?

class A 
{ 
    public: 
     ... 
     int *foo() const 
     { 
      return _px; 
     } 
    private: 
     int *_px; 
} 

Chức năng thành viên foo trả về một con trỏ không const để private viên _px, trong đó, tôi nghĩ rằng, sẽ mở ra một cánh cửa để sửa đổi thành viên _px, phải không?

foo một chức năng thành viên const? Tôi có nên thêm const trước loại trả lại không?

CẬP NHẬT

Thật là một const thành viên-chức năng nên đảm bảo là, nó không thể thay đổi bất kỳ dữ liệu thành viên, phải không?

Trong trường hợp của tôi, chức năng foo không mở một cánh cửa để sửa đổi class A s dữ liệu thành viên _px, nhưng một cánh cửa để sửa đổi những gì _px trỏ đến, Vì vậy, câu hỏi của tôi là, điều này vi phạm những gì một const chức năng cần đảm bảo ?

+1

Trình biên dịch nói với cảnh báo được bật? – Arunmu

+2

@ArunMu gcc 4.6.1 không nói gì cả. – jrok

+0

@ArunMu, vâng, dường như không có gì. – Alcott

Trả lời

27

Chức năng thành viên const chỉ có thể trả lại con trỏ const hoặc tham chiếu đến thành viên.

Tuy nhiên, ví dụ của bạn không trả lại con trỏ cho thành viên; nó trả về một bản sao của một thành viên xảy ra là một con trỏ. Điều đó được cho phép trong một hàm thành viên const (ngay cả khi con trỏ xảy ra để trỏ đến một thành viên khác).

này sẽ không được phép (lưu ý rằng nó bây giờ trả lại một tài liệu tham khảo):

int *& foo() const {return _px;} 

nhưng điều này sẽ (trở về một tham chiếu const):

int * const & foo() const {return _px;} 
+0

Thưa bạn, lời giải thích của bạn khá rõ ràng và đúng. IMO, 'foo' trong' lớp A' mở một cánh cửa để sửa đổi những gì '_px' trỏ tới, cái mà, tôi nghĩ, làm cho' foo' thành một hàm không phải thành viên, đúng không? – Alcott

+0

@Alcott: 'const' trên một hàm thành viên chỉ bảo vệ các thành viên của đối tượng, không phải bất kỳ cấp độ gián tiếp nào khác. Vì vậy, trong hàm '_px' có hiệu quả' int * const'; bản thân con trỏ không thể sửa đổi được, nhưng mục tiêu của nó có thể là. –

4

int *_px trở thành int *const _px bên trong một thành viên const hàm này ngụ ý rằng con trỏ không thể được reseated nhưng dữ liệu được trỏ tới vẫn có thể sửa đổi được. Hơn nữa chức năng của bạn trả về một bản sao của con trỏ vì vậy nó không quan trọng anyways.

1

Có, trong trường hợp của bạn, có thể. Tuy nhiên, nó thường được khuyên nên không để làm điều này, bởi vì nó cho phép thay đổi đối tượng liên tục:

void f(const A& a) 
{ 
    *(a.foo()) = 42; // damn! 
} 
3

Nó không mở một cánh cửa để sửa đổi _px mà là những gì _px điểm đến. Bạn quyết định có muốn cho phép điều này hay không.

Ví dụ: iterator::operator-> sẽ trả lại con trỏ không phải là const và const_iterator::operator-> sẽ trả về một con trỏ const. Cả hai phương pháp có thể được const mình.

+0

Có, nó sẽ mở ra một cánh cửa để sửa đổi những gì '_px' trỏ đến. – Alcott

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