我有一个学生,有一个整数变量
class Student {
int id;...
};
有时id指的是学生的id,有时它指的是自动生成的 与学生的身份完全无关的身份证明(也许学生没有身份证明 在所有或做了,被忽略了)。问题是,处理学生算法时必须改变他们的算法 基于id是来自学生还是自动生成的行为。
我在想添加一个额外的字段(bool)来指定哪个是哪个。但是这个 导致两个领域不同步的危险。
或者有 一个枚举而不是一个布尔。但我觉得必须有更好的方法来指定这一点 以更加面向对象的方式。
答案 0 :(得分:2)
我正在考虑添加一个额外的字段(bool)来指定哪个是 哪一个。但这会导致两个字段不同步的危险。
这就是数据隐藏的内容。如果您将这两个字段设为私有,则可以通过公共成员函数控制它们保持同步,例如
class Student {
public:
Student()
:id_(rand()),
autogen_(true)
{}
Student(int id)
:id_(id),
autogen_(false)
{}
void SetID(int id)
{
id_ = id;
autogen_ = false;
}
int GetID() const { return id_; }
private:
int id_;
bool autogen_;
};
答案 1 :(得分:1)
如果自动生成的数字仅为正数,则可以在分配学生ID时添加负号。这可以让您区分自动生成和指定的ID。使用ID时,您可以获得绝对值。
答案 2 :(得分:1)
我为enum投票 - 它使代码比bool更具可读性,它可能会占用尽可能多的内存,然后你可以扩展它,如果你需要有第三种ID。
答案 3 :(得分:1)
我不太了解或关心OOP理论,但您可以对该类型的信息进行编码。
// tagged_id<T1> and tagged_id<T2> are distinct types that convert to int
template <typename Tag>
struct tagged_id {
int id;
explicit tagged_id(int id) : id(id) {}
operator int() const { return id; }
};
struct student {
struct autogenerated_id;
struct real_student_id;
// variant is a tagged union of types — it'll either be one or the other
boost::variant<tagged_id<autogenerated_id>, tagged_id<real_student_id>> id;
};
您可以阅读有关如何对存储值采取行动的Boost.Variant文档。
答案 4 :(得分:0)
听起来好像你可以使用一个“基础学生”类来定义处理算法如何处理学生对象的界面,然后为每种类型的ID(学生ID或自动生成)分别创建派生类其中包含派生类中定义的适当处理处理逻辑。这是一种更面向对象的设计。