从公共接口继承时,为什么实现是公共的还是私有的并不重要? 我可能很好,只是疲劳或太长,远离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; }

从公共接口继承时,为什么实现是公共的还是私有的并不重要? 我可能很好,只是疲劳或太长,远离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; },c++,inheritance,virtual,C++,Inheritance,Virtual,我希望编译器和/或链接器会抱怨函数签名错误或至少是缺少实现。考虑到这是可行的,当它被顶级声明隐藏时,public/protected/private修饰符的含义是什么 此规则如何调用C++?< p>标准中的第11条第1款: 访问规则第11条适用于 虚函数是由它的性质决定的 声明和声明不受 函数的规则,该函数稍后 覆盖它。[示例-与您的基本相同] 在呼叫点检查访问 使用所用表达式的类型 表示对象,该对象的 调用成员函数。通道 中的类中的成员函数的 它的定义通常是不正确的 知道 本标准第11.6.1

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


此规则如何调用C++?

< p>标准中的第11条第1款:

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


本标准第11.6.1段对此进行了规定:

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

这是因为函数名是基于对象的静态类型解析的

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

还要注意,公共、私有和受保护的可访问性都是编译时构造。在运行时,没有这样的事情。编译器只能在编译时检测与可访问性相关的任何违反规则的行为。它无法知道运行时会发生什么

因此,即使我指向一个类型为Usage的对象,它在private部分定义了bb,编译器也可以使用它,正如前面提到的,静态类型i仍然是Interface*,它有一个公共函数bb。编译器不关心对象的动态类型以及它如何重写函数,因为它不能,正是因为它是动态的;它是在运行时确定的

这是因为函数名是基于对象的静态类型解析的

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

还要注意,公共、私有和受保护的可访问性都是编译时构造。在运行时,没有这样的事情。编译器只能在编译时检测与可访问性相关的任何违反规则的行为。它无法知道运行时会发生什么


因此,即使我指向一个类型为Usage的对象,它在private部分定义了bb,编译器也可以使用它,正如前面提到的,静态类型i仍然是Interface*,它有一个公共函数bb。编译器不关心对象的动态类型以及它如何重写函数,因为它不能,正是因为它是动态的;它是在运行时确定的。

private意味着您不能从它继承。您可以从中继承受保护的或公共的,但没有任何东西阻止您将可见性限制在较低的级别,即从公共到受保护的或私有的;或者在顶级类中被保护为私有。

私有意味着您不能从它继承。您可以从中继承受保护的或公共的,但没有任何东西阻止您将可见性限制在较低的级别,即从公共到受保护的或私有的;或者在你的头等舱里被保护成私人舱。

Ha,就是这样,你抓到我了。完美答案。哈,就是这样,你抓住我了。完美答案。
Interface* i = new Usage();
std::cout << i->bb() << std::endl;