3

在 C++(03) 类中,我有一个成员变量,必须在对象构造期间为其赋值。但是,只有派生类可以计算所需的值。正如这篇文章中所讨论的,C++ 是否要求您从其派生类初始化基类成员?,我知道派生类不能初始化基类成员,但是赋值对我来说就足够了。

因此,我在基类中提供了一个方法来分配一个值,但我不知道如何强制派生类调用它。下面的示例代码说明了这一点。

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。我可以在那里检查它,但这样做太乏味、容易出错且效率低下。

如果以前有人问过这个问题,我深表歉意。在通过搜索“确保派生类构造函数必须调用特定的基类方法”和“强制派生类分配基类成员”来询问之前,我确实尝试在这里找到它。我遇到了一些有用的帖子如何在 C++ 中的派生类的构造函数中初始化基类的 const 变量?强制派生类使用基类的构造函数,但不幸的是他们没有解决我的问题。

您能否建议我一种合适的方法来解决这种情况?编译时检查解决方案是可取的,但如果不可能,运行时检查也会有所帮助。虽然我不能使用 C++11 来解决我的问题,但我也很乐意学习任何 C++11 解决方案。感谢您的考虑。

编辑当然,将其记录为要求也是一种选择,但我想了解是否有程序化解决方案。

Edit2我同意应该在构造函数参数中传递值的答案,如果我必须Base从头开始编写,我不会要求这种方法。问题是由于遗留原因,Base已经有几个构造函数参数(9),我希望通过将它们“卸载”到构造函数主体来避免添加更多参数(3)。但从长远来看,必须重构代码。

Edit3对这么多的编辑感到抱歉。我可以随意修改Base课程,但Derived课程在客户端代码中,我无法控制。

4

3 回答 3

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;
    }
};
于 2012-12-09T13:47:40.987 回答
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,也可以是任何进行计算的函数。

于 2012-12-09T13:50:28.350 回答
0

我认为不可能强制派生类在其构造函数中调用基类方法。您可能能够通过其他响应中的技术强制实现/调用,但据我所知,绝对确保它在 Derived 的构造函数中完成是不可能的,除非可以修改基类

于 2012-12-09T13:57:11.610 回答