【发布时间】:2015-11-11 22:09:02
【问题描述】:
考虑以下几点:
class base {
// base class
public:
void doBaseStuff() {
/* do something basic */
}
private:
int someDataMember;
};
class derived : public base {
// this class inherits 'doBaseStuff()' as well as 'someDataMember'
public:
void doDerivedStuff() {
/* do something in addition that only this type of derived class can do */
}
};
class specialDerived : public base {
// say 'doBaseStuff()' doesn't make sense in the context of this class!
// we do not want to inherit that function here
// is there a way to prevent instances of this class from calling it?
// we still want 'someDataMember', so we must derive from the base class
public:
void doSpecialStuff() {
/* do something in addition that only this special derived class can do */
}
};
有一个类可以作为多个其他类的公共基类。但是,假设它在派生类之一中不需要的基类成员函数之一。有没有办法明确禁止派生类中的继承函数?
实际上,我们可以谈论一个有 1000 个成员的基类,而我们想要继承其中的 999 个,因此简单地放弃继承并复制所有代码会导致代码的可维护性非常差。
在基类中使该函数成为虚拟函数,并在specialDerived 类中提供它的虚拟实现是可行的。但是,如果该函数有一个实际的返回类型,而不是void,该怎么办?然后specialDerived 类必须提供一个返回值的实现。然后调用者可以假设他们得到的值是有意义的,而实际上并非如此,这是一个问题。
只需在 specialDerived 中使用单个 throw 在主体中实现虚函数可能是一种解决方案,只要存在一些明确指出在此特定派生类型的对象上调用此函数没有意义的文档,并且这个操作会抛出。我认为这是一种可能的解决方案,但我不确定这是否是最好的方法。
【问题讨论】:
-
您不能阻止对您继承的非虚函数的调用。就此而言,您不能阻止调用公共成员函数的基类实现。但是你可以简单地避免继承。
-
继承是
is-a关系,如果它的一个(或多个)操作对您没有意义,显然这不是is-a关系,所以您的问题是您不应该首先继承。 -
@adam10603 第一时间实施正确的接口!无论您使用的是动态(纯虚函数)还是静态(查找 CRTP)多态性。事实上,您的设计存在严重缺陷。
-
@adam10603 如果您无法返回合理的值,请改为抛出异常。一般来说,我们无法判断这是否是错误行为,这完全取决于您的实际用例。
-
抛出异常似乎是一个合适的回应。
标签: c++ class inheritance member virtual-functions