Hãy xem xét các lớp sau đây:Sử dụng giá trị trình bao bọc và toán tử() quá tải để đơn giản hóa thiết kế getter/setter: một thực tế nguy hiểm?
class MyClass1
{
public:
double x() const {return _x;} // getter
double y() const {return _y;} // getter
double z() const {return _x*_y;} // getter
void x(const double var) {_x = var;} // setter
void y(const double var) {_y = var;} // setter
void z(const double var) {_x = var; _y = 1;} // setter
protected:
double _x;
double _y;
};
Như các nội dung thực tế của MyClass1
là một chi tiết thực hiện, các getter và setter cung cấp một cách thống nhất để có được và thiết lập các nội dung lớp học ngay cả khi họ interdependant (ở đây _z
không tồn tại bên trong nhưng đối với người dùng, z
là một biến số như x
và y
).
Bây giờ để tránh phải viết getter/setter cho x
và y
, người ta có thể sử dụng một wrapper như thế này:
template <typename Type>
class Wrapper
{
public:
constexpr Wrapper(const Type& value) {_value = value;}
constexpr Type& operator()() {return _value;}
constexpr const Type& operator()() const {return _value;}
constexpr void operator()(const Type& value) {_value = value;}
protected:
_value;
};
Và bây giờ lớp ban đầu trở thành:
class MyClass2
{
public:
Wrapper<double> x;
Wrapper<double> y;
double z() const {return x*y;} // getter
void z(const double var) {x = var; y = 1;} // setter
};
Có một thực hành nguy hiểm hoặc một giải pháp tốt để tránh phải viết getters/setters?
Lưu ý: Ở đây MyClass1
và MyClass2
chỉ là ví dụ. Câu hỏi của tôi là rất "chung": là nguy hiểm để thay thế getters/setters của các lớp học theo đề nghị Wrapper
khi getter/setter chỉ trả về/thiết lập một giá trị nội bộ.
Tôi cho rằng bạn sẽ cần phải thực hiện một số loại hành vi để thực sự làm điều gì đó (xác thực, thông báo, vv) trên các accessors. Othewise họ sẽ đánh bại mục đích của việc có chúng. Bạn không nghĩ sao? imho – imreal
tại sao lớp học của bạn cần có/thiết lập giao diện? nếu các hàm này không phải duy trì một bất biến lớp, thì có rất ít điểm trong việc mã hóa chúng. – TemplateRex