如何避免私有函数使用基类虚函数间接调用。
class baseclass{
public:
virtual void printmynumber() = 0;
};
class derivedclass : public baseclass
{
private:
int m_mynumber;
void printmynumber()
{
cout << m_mynumber << endl;
}
public:
derivedclass(int n)
{
m_mynumber = n;
}
};
void main()
{
baseclass *bObj = new derivedclass(10);
bObj->printmynumber();
delete bObj;
}
如何避免调用私有函数?
答案 0 :(得分:2)
你不能。
void printmynumber()
是baseclass
(因此derivedclass
)的公共API的一部分。如果您希望derivedclass::printmynumber()
不公开,也许derivedclass
不应从baseclass
继承。
如评论中所建议,这违反了Liskov substitution principle:L in SOLID。
答案 1 :(得分:2)
您不能通过继承做到这一点。给定指向baseclass
的指针,编译器仅知道它具有public
virtual
函数,因此允许相应地调用该函数。
派生类选择从基类继承,并实现了具有不同访问权限的函数。但是,仅给出指向基础的指针,这些都不可见。
没有什么可以阻止derivedclass::printmynumber()
被实现为不做任何事情的-这意味着如果代码调用它,将不会有明显的效果(假设没有预期的效果是可以容忍的)。
真正的解决方案是修复您的设计,而不是尝试解决设计中的缺陷。不要从derivedclass
继承baseclass
。这样,derivedclass
的成员函数根本无法调用,仅给出指向baseclass
的指针,因为类型不相关(将derivedclass *
传递给期望{{ 1}}通常会被诊断为错误。
顺便说一句:baseclass *
返回main()
,而不是int
。一些编译器支持void
作为非标准扩展(某些编译器的文档错误地描述了这种标准),但是最好避免。
答案 2 :(得分:2)
我看到的在不修改基类的情况下阻止它的唯一方法是在原始基类和最终派生类之间添加另一个继承层。在该中产阶级中,您可以将该函数设为私有或删除。然后,您使用指向该中产阶级的指针作为基础指针。
类似
class baseclass
{
public:
virtual void printmynumber() = 0;
};
struct middleclass : public baseclass
{
void printmynumber() = delete;
};
class derivedclass : public middleclass
{
private:
int m_mynumber;
void printmynumber()
{
cout << m_mynumber << endl;
}
public:
derivedclass(int n)
{
m_mynumber = n;
}
};
void main()
{
// Here use the middleclass instead of the baseclass
middleclass *bObj = new derivedclass(10);
// printmynumber is deleted in the middleclass and can't be called
// This will result in a build error
bObj->printmynumber();
delete bObj;
}
这当然需要修改使用原始基类的所有位置,但是不需要对基类本身进行修改。所以这是一个权衡。