使用虚函数访问私有函数

Accessing Private function using virtual function

如何避免使用基 class 虚函数间接调用私有函数。

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;
}

如何避免私有函数的调用?

你不能。

void printmynumber()baseclass 的 public API 的一部分,因此是 derivedclass 的一部分。如果您希望 derivedclass::printmynumber() 不是 public,也许 derivedclass 不应该继承自 baseclass

如评论中所建议,这违反了 Liskov substitution principle: the L in SOLID

继承不能做到这一点。给定一个指向 baseclass 的指针,编译器只知道它有一个 public virtual 函数,因此允许相应地调用该函数。

派生class已选择从基础class继承,并实现了具有不同访问权限的功能。但是其中 none 是可见的,只给出一个指向基数的指针。

没有什么可以阻止 derivedclass::printmynumber() 被实现为什么都不做 - 这意味着如果代码调用它,将不会有任何可观察到的效果(假设没有预期效果是可以容忍的)。

真正的解决方案是修复您的设计,而不是尝试解决其中的缺陷。不要从 baseclass 继承 derivedclass。这样,根本无法调用 derivedclass 的成员函数,仅给出指向 baseclass 的指针,因为类型不相关(将 derivedclass * 传递给期望 baseclass * 通常会被诊断为错误)。

顺便说一句:main() returns int,而不是 void。一些编译器支持 void main() 作为非标准扩展(并且其中一些编译器的文档错误地将这种东西描述为标准)但最好避免使用。

我能看到在不修改基础 class 的情况下阻止它的唯一方法是在原始基础 class 和最终派生的 class 之间添加另一个继承层].在那个中间 class 您将函数设为私有或删除。然后你使用指向中间 class 的指针作为基指针。

类似

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;
}

这当然需要修改所有使用原始基class的地方,但不需要修改基class本身。所以这是一个权衡。