Thường khá khó hiểu đối với người mới sử dụng C++ mà hàm thành viên được phép gọi các phương thức không phải const trên các đối tượng được tham chiếu bởi lớp (hoặc bằng con trỏ hoặc tham chiếu). Ví dụ, sau đây là hoàn toàn chính xác:Tuyên truyền constness thành dữ liệu được chỉ định bởi các biến thành viên
class SomeClass
{
class SomeClassImpl;
SomeClassImpl * impl_; // PImpl idiom
public:
void const_method() const;
};
struct SomeClass::SomeClassImpl
{
void non_const_method() { /*modify data*/ }
};
void SomeClass::const_method() const
{
impl_->non_const_method(); //ok because impl_ is const, not *impl_
};
Tuy nhiên, đôi khi nó sẽ là khá tiện dụng nếu constness sẽ tuyên truyền để các vật nhọn (Tôi tự nguyện sử dụng thành ngữ pImpl bởi vì nó là một trong những trường hợp mà tôi nghĩ " constness tuyên truyền "sẽ rất hữu ích).
Khi sử dụng con trỏ, điều này một cách dễ dàng có thể đạt được bằng cách sử dụng một số loại con trỏ thông minh với các nhà khai thác quá tải trên constness:
template < typename T >
class const_propagating_ptr
{
public:
const_propagating_ptr(T * ptr) : ptr_(ptr) {}
T & operator*() { return *ptr_; }
T const & operator*() const { return *ptr_; }
T * operator->() { return ptr_; }
T const * operator->() const { return ptr_; }
// assignment operator (?), get() method (?), reset() method (?)
// ...
private:
T * ptr_;
};
Bây giờ, tôi chỉ cần phải sửa đổi SomeClass::impl_
là một const_propagating_ptr<SomeClassImpl>
để có được những hành vi truy nã .
Vì vậy, tôi có một vài câu hỏi về vấn đề này:
- Có một số vấn đề với công tác tuyên truyền constness mà tôi đã bỏ qua?
- Nếu không, có thư viện nào cung cấp các lớp học để có được tuyên truyền về độ chói không? Sẽ không hữu ích nếu các con trỏ thông minh thông thường (unique_ptr, shared_ptr, v.v.) cung cấp một số ý nghĩa để có được hành vi này (ví dụ thông qua một tham số mẫu)?
Nếu tôi chỉ sao chép con trỏ thông minh thì sao? Thì đấy, tôi có một cái không phải. –
'T const * const toán tử ->() const {return ptr_; } '- có lẽ không cần đến' const' thứ hai ở đây –
@Alf và @robin: Bản phác thảo mà tôi đưa ra có thể thực hiện có thể được rải rác với các lỗi (mặc dù kích thước ngắn của nó :)), nó không phải là điểm trung tâm của câu hỏi. Tuy nhiên, phản hồi của bạn thực sự được đánh giá cao! Về vấn đề sao chép, tôi không thấy tại thời điểm này, chúng ta có thể ngăn chặn điều đó bằng cách nào, nhưng thường thì bạn không thể ngăn mình hoàn toàn tự bắn mình vào chân (ví dụ, bạn luôn có thể 'const_cast' đi lệch, nó không có nghĩa là const là vô ích). Liên quan đến bình luận thứ hai, bạn đúng @robin, tôi đã làm điều đó để ngăn chặn 'ptr_' khỏi bị ... –