为什么 c++ 编译器 (VS2013) 选择了错误的函数
Why c++ compiler (VS2013) chooses wrong function?
-
第一种情况
#include <iostream> class A { public: virtual void Write(int i) { std::wcout << L"Write(int) is called" << std::endl; } virtual void Write(wchar_t c) { std::wcout << L"Write(wchar_t) is called" << std::endl; } }; int _tmain(int argc, wchar_t* argv[]) { A *p = new A(); int i = 100; p->Write(i); return 0; }
完美工作。
程序输出
Write(int( 被调用
2.第二种情况。
只需将第一个函数移动到基类:
#include <iostream>
class Base
{
public:
virtual void Write(int i)
{
std::wcout << L"Base::Write(int) is called" << std::endl;
}
};
class Derived: public Base
{
public:
virtual void Write(wchar_t c)
{
std::wcout << L"Derived::Write(wchar_t) is called" << std::endl;
}
};
int _tmain(int argc, wchar_t* argv[])
{
Derived *p = new Derived();
int i = 100;
p->Write(i);
return 0;
}
程序输出
派生::写入(wchar_t( 被调用
但我期望"Base::Write(int(被调用">
第二种情况有什么问题?
你的编译器是对的。
在派生类中定义成员函数时,基类中同名的成员函数将被隐藏。
您可以使用using
将其导入派生类范围,使重载按预期工作。
class Derived: public Base
{
public:
using Base::Write;
virtual void Write(wchar_t c)
{
std::wcout << L"Derived::Write(wchar_t) is called" << std::endl;
}
};
编辑
函数重载不会通过不同的范围。当您在 Derived
上调用 Write
时,将在Derived
类范围中找到名为 Write
的成员函数,然后名称查找将停止,因此永远不会考虑重载解析Base
中的Write
,即使基类版本在这里更合适。
请参阅名称查找
我想这是因为程序找到了该函数的"较新"版本,该版本在隐式转换中是正确的,因此它不会寻找"更好"的函数在父类中调用。我建议:1( 避免使用可互换的参数重载/重新定义函数。2(如果你真的想调用Derived::Write,请使用:
p->Derived::Write(i);
相关文章:
- 链接器错误:函数的多个定义
- 编译器错误:函数调用在常量表达式中必须有一个常量值
- 错误:函数声明符之后的预期函数体
- C 错误 - 函数不能超载
- 如何修复传递参数时调用错误函数的主函数?(C++)
- 错误:函数调用中有两个参数
- 错误:函数不是“类”的静态数据成员 - C++
- C ,G 编译错误函数
- CMake 解析错误函数缺少结尾")"。而是找到带有文本的未终止字符串")
- C++ 错误 函数 2 的多重定义
- 错误:函数调用中从int到int(*)[4]的转换无效
- C++14 自动扣除错误:函数返回一个数组
- 视觉C++错误:函数必须返回一个值
- 错误:函数声明中的两种或多种数据类型
- 错误:函数未在作用域中声明
- rtw_android.c错误:函数“strnicmp”的隐式声明[-Weror=隐式函数声明]
- 错误:函数中的return语句没有值,返回“void*”[-fpermission]
- 简单程序中的链接器错误:函数的多重定义
- 错误:函数参数太多
- 错误:函数__tmaincrtstartup中引用的未解析的外部符号_main