【问题标题】:When inheriting from public interface, why it doesn't matter if the implementation is public or private?从公共接口继承时,为什么实现是公共的还是私有的并不重要?
【发布时间】:2011-06-27 12:47:22
【问题描述】:

我可能只是累了或者离 C++ 太远了,但是今天这个真的让我很惊讶:

#include <iostream>

class Interface
{
public:
    virtual int aa() const = 0;
    virtual int bb() const = 0;
};

class Usage : public Interface
{
private:
    virtual int aa() const
    {
        int a = 10 * 10;
        return a;
    }

    virtual int bb() const
    {
        int b = 20 * 20;
        return b;
    }
};

int main(int argc, char* argv[])
{
    Interface* i = new Usage();
    std::cout << i->bb() << std::endl;

    return 0;
}

我希望编译器和/或链接器会抱怨函数签名错误或至少缺少实现。考虑到这是可行的,当它被顶级声明隐藏时,public/protected/private 修饰符的含义是什么?

这个规则在 C++ 中是如何调用的?

【问题讨论】:

    标签: c++ inheritance virtual


    【解决方案1】:

    这在标准的第 11.6.1 段中有规定:

    访问规则(第 11 条) 虚函数由其决定 声明,不受 稍后的函数的规则 覆盖它。 [示例 - 与您的基本相同] 在呼叫点检查访问 使用所用表达式的类型 来表示对象 成员函数被调用。访问 类中的成员函数 它的定义通常不是 已知。

    【讨论】:

    • 哈,就是这样,你找到我了。完美的答案。
    【解决方案2】:
    Interface* i = new Usage();
    std::cout << i->bb() << std::endl;
    

    这是有效的,因为函数名称是根据对象的 static 类型解析的。

    这里的对象是i,它的static类型是Interface*,它有一个public函数名bb()。因此,编译器没有发现任何问题,因为调用成员函数的要求满足了它。

    另请注意,可访问性(publicprivateprotected)是编译时构造。在运行时,没有这样的事情。编译器只能在编译时检测任何违反与可访问性相关的规则。它无法知道运行时会发生什么。

    因此,即使i 指向一个类型为Usage 的对象,该对象已在private 部分中定义了bb(),编译器也可以使用它,如static 类型的@987654336 之前所述@ 仍然是 Interface*,它具有 public 函数 bb()。编译器不关心对象的 dynamic 类型以及它如何覆盖函数,因为它不能,正是因为它的 dynamic;它在运行时确定。

    【讨论】:

      【解决方案3】:

      private 表示你不能继承它。 protectedpublic 您可以继承,但没有什么能阻止您将可见性限制在顶部的较低级别(即 publicprotectedprivate;或 protectedprivate)类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-25
        • 2011-01-05
        • 2011-08-29
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 1970-01-01
        • 2011-07-23
        相关资源
        最近更新 更多