为什么 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.Second 例。
只需将第一个函数移动到基础 class:
#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;
}
程序输出
Derived::Write(wchar_t) 被调用
但我预计 "Base::Write(int) is called"
第二种情况有什么问题?
我猜这是因为程序找到了函数的 "newer" 版本,它与隐式转换是正确的,所以它没有寻找 "better" 函数来调用父 [=17] =].
我建议:
1) 避免 overloading/redefining 具有可互换参数的函数。
2) 如果你真的想要 Derived::Write 被调用,使用 :
p->Derived::Write(i);
你的编译器是对的。
当您在派生class中定义成员函数时,基class中的同名成员函数将被隐藏。
您可以使用 using
将其导入派生的 class 作用域,使重载工作如您所愿。
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
class 范围内找到名为 Write
的成员函数,然后 name 查找 将停止,因此 Base
中的 Write
将永远不会被考虑用于 过载解决方案 ,即使基础 class 版本是在这里更合适。
第一种情况
#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.Second 例。
只需将第一个函数移动到基础 class:
#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;
}
程序输出
Derived::Write(wchar_t) 被调用
但我预计 "Base::Write(int) is called"
第二种情况有什么问题?
我猜这是因为程序找到了函数的 "newer" 版本,它与隐式转换是正确的,所以它没有寻找 "better" 函数来调用父 [=17] =]. 我建议: 1) 避免 overloading/redefining 具有可互换参数的函数。 2) 如果你真的想要 Derived::Write 被调用,使用 :
p->Derived::Write(i);
你的编译器是对的。
当您在派生class中定义成员函数时,基class中的同名成员函数将被隐藏。
您可以使用 using
将其导入派生的 class 作用域,使重载工作如您所愿。
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
class 范围内找到名为 Write
的成员函数,然后 name 查找 将停止,因此 Base
中的 Write
将永远不会被考虑用于 过载解决方案 ,即使基础 class 版本是在这里更合适。