让我们假设我想对命题公式进行建模。
公式是命题,公式的否定,两个公式的结合或两个公式的分离。
另外,公式与真值相关联(即真或假)。
理想情况下,我希望对其进行建模:
class Formula { // abstract class
protected:
bool value;
public:
~Formula() = 0;
};
class Proposition : public Formula {
private:
string name;
public:
Proposition(string s, bool b) : value(b), name(s) {}
};
class Negation : public Formula {
private:
Formula* f;
public:
Negation(Formula* nested) : value(!nested->value), f(nested) {}
};
class Conjunction : public Formula {
private:
Formula* l;
Formula* r;
public:
Conjunction(Formula* f1, Formula* f2) : value(f1->value && f2->value), l(f1), r(f2) {}
};
// Disjunction similar to Conjunction
但是,我无法访问value
,nested
和f1
的{{1}}属性(请参阅https://stackoverflow.com/a/12271018/3923424例如。)
为了克服这个问题,我添加了一个公共函数f2
,但我发现它并不优雅
我还想避免公开get_value()
,因为其他类不应该修改此属性
最后,我可以使value
的所有派生类成为朋友。但我并不完全相信这是最好和/或最简单的解决方案。
有没有一种优雅的方法来解决这个问题?
奖金问题:如果我希望Formula
只能由派生类访问,该怎么办?
答案 0 :(得分:0)
您可以在Formula
中使用受保护的静态getter来实现此目的:
class Formula {
protected:
bool value;
static bool getValue(Formula& f) {
return f.value;
}
Formula(bool value) : value(value) {}
public:
virtual ~Formula() = 0;
};
...然后
class Conjunction : public Formula {
private:
Formula* l;
Formula* r;
public:
Conjunction(Formula* f1, Formula* f2) :
Formula(Formula::getValue(*f1) && Formula::getValue(*f2)),
l(f1), r(f2) {}
};
Here是一个充实的例子。
答案 1 :(得分:0)
如果您希望数据成员为protected
以防止其被更改,您仍然可以公开显示常量值。这可以是普通的const
吸气剂(静态或非静态)形式,或者是const bool
的类型转换算子形式,即
class Formula {
protected:
bool value;
public:
/* ... */
operator bool() const { return value; }
};