0
#include <iostream>

class A{
public:
  void printit(register int b) {
     std::cout<<"inside A";
  }
};

class C:public A{
public:
  void printit(int b) {
     std::cout<<"inside C";
  }
};

int main() {
C c;
c.printit(1);
return 0;
}

在上面的代码中,printit 是 C 中的一个重写方法,没有存储类寄存器。但是,编译器仍然匹配,并且代码打印“在 C 中”。为什么寄存器 int 与 int 匹配?

4

2 回答 2

6

C++ 存储类从未参与过重载决议。这是出于显而易见的原因:存储类修改特定变量的内存的来源/方式。重载决议是关于用于调用函数的表达式的性质。表达式并没有真正的存储类。

是的,表示具有存储类的变量的表达式可以说是具有存储类。但是表达式也可以是对变量的各种计算。或文字。或函数返回值。这些东西都没有存储类。

因此,虽然您可以声明一个参数使用register存储类(在某种程度上,这register在 C++ 中仍然存在。C++11 弃用了这种关键字的使用,而 C++17 及更高版本正式删除了它),但这并没有意味着它参与了重载决议。它只影响所讨论的参数变量如何获取其内存(register当然,在某种程度上,在 C++ 中具有任何行为)。

除此之外,如果您从基类继承并创建与基类方法同名的方法,则基类方法将被隐藏,除非您使用using声明将它们带回。因此,即使存储类以某种方式参与了重载解决方案,您的代码仍然无法正常工作。

于 2020-06-05T18:13:32.960 回答
1

该对象是 type C,它会调用 class 中的方法C,它不知道基类中是否存在另一个方法。事实上,它不知道基类的存在。

关于在其中一个参数中使用的重载register,它不会区分参数,因为它不是类型,它是使变量存储在处理器寄存器而不是“普通”内存中的关键字。

一个更简单的检查方法是尝试在同一个类中重载:

class A {
public:
    void printit(int b);
    void printit(register int b);
};

您将遇到编译错误:

'void A::printit(int)' cannot be overloaded with 'void A::printit(int)'

请注意,ISO C++17 删除了register存储说明符。

于 2020-06-05T18:16:51.200 回答