在C ++(03)类中,我有一个成员变量,必须在对象构造期间分配一个值。但是,只有派生类才能计算所需的值。正如本文Does C++ require you to initialize base class members from its derived class?中所讨论的,我理解派生类不能初始化基类成员,但是赋值对我来说已经足够了。
因此,我在基类中提供了一个赋值的方法,但我无法弄清楚如何强制派生类调用它。以下示例代码说明了这一点。
class Base {
public:
Base() {}
setFoo(unsigned inFoo) { foo = inFoo; }
private:
unsigned foo;
};
class Derived : public Base {
Derived() : Base() {
unsigned desired = ... // do calculations to get the desired value
setFoo(desired); // --> how to ensure that derived class calls this?
}
};
然后,其他几个基类方法使用foo
。即使我在setFoo()
中设置了“标志”,也没有“后构造函数”方法可以检查它。基类中还有其他几种使用foo
的方法。我可以在那里检查它,但它太繁琐,容易出错并且效率低下。
如果之前有人问过,我道歉。在尝试通过搜索“确保派生类构造函数必须调用特定基类方法”和“强制派生类来分配基类成员”之前,我确实尝试在此处找到它。我发现了一些有用的帖子How can I initialize a const variable of a base class in a derived class' constructor in C++?和Force a Derived Class to use the Constructor of the Base Class,但遗憾的是他们没有解决我的问题。
您能否建议我采取合适的方法来解决这种情况?编译时检查解决方案是可取的,但如果不可行,运行时检查也会有所帮助。虽然我不能将C ++ 11用于我的问题,但我也很乐意学习任何C ++ 11解决方案。谢谢你的考虑。
编辑当然,将此作为一项要求进行记录也是一种选择,但我想了解是否有程序化解决方案。
Edit2 我同意答案,说应该在构造函数参数中传递值,如果我必须从头开始编写Base
,我就不会要求这种方法。问题在于,由于遗留原因,Base
已经有几个构造函数参数(9),我希望通过将它们“卸载”到构造函数体来避免添加更多(3)。从长远来看,代码必须重构。
Edit3 很抱歉这么多次修改。我可以随意修改Base
类,但Derived
类在客户端代码中,我无法控制。
答案 0 :(得分:9)
如果派生类构造函数必须调用setFoo()
,那么我认为这是一个设计问题。设计基类更好,这样它的构造函数将所需的值作为参数,并让派生类将计算值传递为:
class Base {
public:
Base(unsigned int foo) : m_foo (foo) {} //define this constructor
private:
unsigned int m_foo; //member data
};
class Derived : public Base {
Derived() : Base(computeValue())
{
}
private:
static unsigned int computeValue() //it may take argument(s)
{
unsigned int desired = ... //do calculations to get the desired value
return desired;
}
};
答案 1 :(得分:2)
如果构造对象需要一个值,它应该是构造函数的参数。
class Base {
public:
Base(unsigned inFoo) { setFoo(inFoo); }
setFoo(unsigned inFoo) { foo = inFoo; }
private:
unsigned foo;
};
class Derived : public Base {
Derived() : Base(compute_desired()) { }
};
此处compute_desired
可以是Derived
的成员,也可以是执行计算的任何函数。
答案 2 :(得分:0)
我认为不可能强制派生类在其构造函数中调用基类方法。您可以通过其他响应中的技术强制执行/调用,但绝对确保在Derived的构造函数中完成它是不可能的,尽管我的知识是不可能的,除非可以修改基类