78

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

为什么编译器会这样?还是我做错了什么?

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;
}
4

5 回答 5

66

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

然后该方法与调用的参数不匹配,您会收到错误消息。

有关此主题的更多说明,另请参阅C++ FAQ

于 2009-12-13T15:45:22.200 回答
20

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

请参阅C++ 常见问题解答

于 2009-12-13T15:44:12.623 回答
6

注意事项:在这种情况下需要使用“使用”是一个危险信号,您的代码可能会让其他开发人员感到困惑(毕竟它让编译器感到困惑!)。您可能应该重命名这两种方法之一,以使其他程序员清楚区分。

一种可能:

void action( const char how )
{ 
  takeAction( &how ); 
}
void action( const char * how )
{
  takeAction(how);
}
virtual void takeAction(const char * how) = 0;
于 2013-01-23T22:22:39.483 回答
6

如果在派生类中重新定义任何重载函数,则隐藏基类中的所有重载函数。包含这两种功能的一种方法是避免类中的函数重载。或者您可以使用using关键字。

于 2014-10-07T10:37:57.093 回答
0

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

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

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

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

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

于 2021-08-24T08:21:06.163 回答