Giá trị mặc định không hợp lệ về cơ bản là một biến thể trong thiết kế của bạn. Đối tượng không hợp lệ khi được tạo. Bạn nên tránh điều đó khi số hợp lý. Không có nghĩa là bạn nên tránh nó "bằng mọi giá."
Một số vấn đề yêu cầu bạn phải bắt đầu ở trạng thái biến thể. Trong trường hợp đó, bạn có để lý do về giá trị không hợp lệ đó về mặt tinh thần. Nếu bạn tránh đặt tên cho nó, bạn đang tích cực làm cho mã của bạn ít biểu cảm hơn. Hãy suy nghĩ về nó trong giao tiếp giữa bạn và người sẽ phải duy trì mã sau này.
Đối phó với nó có xu hướng khó chịu. Bạn bắt đầu ở trạng thái biến thể, nhưng vào thời điểm nó có liên quan, bạn hy vọng rằng nó không còn là biến thể nữa. Chiến lược tôi thích là cho phép người dùng bỏ qua trạng thái biến thể và chỉ ném khi tôi đã mắc lỗi.
namespace FooType {
enum EnumValue {
INVALID = 0
,valid
};
}
struct Foo {
Foo() : val(FooType::INVALID) {}
FooType::EnumValue get() const {
if (val == FooType::INVALID)
throw std::logic_error("variant Foo state");
return val;
}
FooType::EnumValue val;
};
Điều này giải phóng người dùng của bạn không phải lý do về phương sai của bạn, điều đáng để tranh giành.
Nếu bạn không thể thoát khỏi điều đó, tôi thường thích làm suy giảm các giao diện an toàn và không an toàn.
struct Foo {
Foo() : val(FooType::INVALID) {}
bool get(FooType::EnumValue& val_) const {
if (val == FooType::INVALID)
return false;
val_ = val;
return true;
}
FooType::EnumValue get() const {
FooType::EnumValue val_;
if (!get(val_))
throw std::logic_error("variant Foo state");
return val_;
}
FooType::EnumValue get_or_default(FooType::EnumValue def) const {
FooType::EnumValue val_;
if (!get(val_))
return def;
return val_;
}
FooType::EnumValue val;
};
Các loại giao diện này phù hợp cho những thứ như cơ sở dữ liệu, nơi giá trị null có thể được mong đợi.
Nguồn
2012-12-19 17:11:14
Bạn có thể có lớp giám sát của mình 'mở rộng' enum bằng cách thêm giá trị MONITORING_STATE? – dchhetri
Tôi có thể không hiểu đầy đủ đề xuất. Trong ví dụ cụ thể này MONITORING_STATE vẫn sẽ không có ý nghĩa nhiều từ quan điểm công việc và, theo [link] (http://stackoverflow.com/questions/1804840/extending-enums-in-c) Tôi không thể mở rộng enum trong lớp giám sát (lý tưởng sử dụng eJobStates dưới dạng biến riêng tư). – ellimilial
Vâng, tôi nhận ra rằng bạn không thể tự nhiên mở rộng enums. monitoring_state chỉ là một cái tên, nhưng bạn chắc chắn có thể sử dụng job_state_unknown. Những gì tôi đã đề nghị là thêm enum bổ sung trong lớp giám sát. Bạn có thể làm điều này bằng cách lấy giá trị enum cuối cùng của eJobStates và thêm 1 vào nó, và làm cho nó trở thành giá trị trạng thái enum bắt đầu cho lớp giám sát. Sau khi tất cả, với enums bạn chỉ đơn giản là so sánh ints đại diện cho các quốc gia. Nếu bạn muốn một cái gì đó cụ thể hơn, sau đó như được đề xuất trong liên kết, bạn có thể tạo ra một lớp Enum, hoặc tạo một đối tượng trạng thái cho mỗi trạng thái. – dchhetri