了解C++继承的范围

Understanding scope with inheritance in C++

本文关键字:范围 继承 C++ 了解      更新时间:2023-10-16

我正在测试我对C++继承的理解,并正在阅读一些示例代码。根据程序输出,在我看来,double add()int add()函数具有不同的作用域,而不是使用参数10.5调用double add()函数,而是从doubleint的隐式类型转换(始终被截断(,而是调用函数int add()。类型转换将解释为什么输出11 11

我的问题如下:

  1. 重载的继承函数的范围是什么?
  2. 什么时候(如果有的话(从doubleint的类型转换无效(即会导致编译时错误(?
  3. 在哪里可以阅读有关 C++ 中继承的命名空间/范围的细微差别的更多信息?
#include <iostream>
using namespace std;
class One {
public: 
double add(double x) { return x + 0.1; } 
};
class Two : public One {
public:
int add(int x) { return x + 1; }
};
int main(int argc, char *argv[]) {
Two obj;
cout << obj.add(10) << " " << obj.add(10.5) << endl;
return 0;
}

> 将add声明为int add(int x) { return x + 1; }从外部作用域隐藏了add的任何其他定义,这与函数中嵌套块中的变量阴影相同的行为。

名称查找始终在作用域中查找名称,然后再在同一作用域中多次出现该名称时进行潜在的重载解析;obj.add(10.5)找到Two::add(),因此不会继续检查外部作用域。

您可以使用 Two 重新声明外部作用域中的函数using One::add;

在转换主题上,double参数始终与int参数匹配。如果双精度值超出int范围,但这是运行时未定义的行为(无需诊断(,则它可能无效。

本主题在 C++ 常见问题解答 中介绍,您还可以查看有关 cpp首选项的名称查找文章.

重载不适用于C++中的继承:

重载不适用于C++编程中的派生类 语言。基础和派生之间没有过载解决方案。 编译器查看派生的范围,找到单个 函数"Double F(double("并调用它。它从不打扰 (封闭(基础范围。在C++中,没有过载 作用域 – 派生类作用域不是此常规的例外 统治

他们使用的示例在派生类中具有double f(double)

https://www.geeksforgeeks.org/does-overloading-work-with-inheritance/

要解决此问题,必须重新设计该类。我无法就如何更改它给出任何具体的反馈,因为该类非常通用。

除了上面的答案之外,我还想补充一点,您可以通过为One::add()创建一个模板来避免重载问题,该模板将允许它接受整数和双精度,然后让类Two继承它。

#include <iostream>
using namespace std;
class One {
public:
template <typename T>  //Template allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type.
double add(T x)
{
if (floor(x) == x) //Check if x is integer
return x + 1;
else              
{
return x + 0.1;
}
}
};
class Two : public One {
public:
//No need for overloading add() here because in Class One, add() function will accept integers and doubles
};
int main(int argc, char* argv[]) {
Two obj;
cout << obj.add(10) << " " << obj.add(10.5) << endl;
return 0;
}