为什么要使用“ using”关键字来访问基类方法?

为了解释我的问题,我编写了下面的代码。如果我注释第11行(使用关键字“ using”) ,编译器将不编译该文件并显示此错误: invalid conversion from 'char' to 'const char*'。它似乎没有在 Son类中看到 Parent类的方法 void action(char)

为什么编译器会这样? 或者我做错了什么?

class Parent
{
public:
virtual void action( const char how ){ this->action( &how ); }
virtual void action( const char * how ) = 0;
};


class Son : public Parent
{
public:
using Parent::action; // Why should i write this line?
void action( const char * how ){ printf( "Action: %c\n", *how ); }
};


int main( int argc, char** argv )
{
Son s = Son();
s.action( 'a' );
return 0;
}
46636 次浏览

令人惊讶的是,这是标准行为。如果派生类声明的方法与基类定义的方法的名称相同,则派生类的方法隐藏基类的方法。

参见 C + + 常见问题解答

在派生类中声明的 action隐藏在基类中声明的 action。如果对 Son对象使用 action,编译器将搜索在 Son中声明的方法,找到一个称为 action的方法,并使用它。它不会在基类的方法中继续搜索,因为它已经找到了匹配的名称。

然后该方法与调用的参数不匹配,就会得到一个错误。

有关这个主题的更多解释,请参见 C + + 常见问题解答

注意: 在这种情况下需要使用“ using”是一个红色标志,您的代码可能会让其他开发人员感到困惑(毕竟它会让编译器感到困惑!).您可能应该重命名这两个方法中的一个,以便其他程序员能够清楚地看到其中的区别。

一种可能性是:

void action( const char how )
{
takeAction( &how );
}
void action( const char * how )
{
takeAction(how);
}
virtual void takeAction(const char * how) = 0;

如果在派生类中重新定义了任何重载函数,那么基类中的所有重载函数都是隐藏的。 同时包含这两个功能的一个方法是避免在类中出现函数重载 可以使用已使用的 using关键字。

通过使用 using,将在基类中声明的名称引入到派生类的命名空间中。

然后,当您在派生类中声明函数集时,编译器通过隐式 this指针的类型将它们与其基类中具有相同参数类型的函数区分开来。

在重载解析期间,需要类类型转换的参数(当指向派生类的指针转换为指向基类的指针时)的优先级最低。

因此,可以区分具有看似相同参数列表的两个函数,并且当从派生类型的对象调用它们时,本地声明的函数将是更好的匹配(如果不是精确的)。

我是一个新手,请指出我的误解。