C++类构造函数是否隐藏基类同名方法?标准条款查询
关于C++构造函数与基类同名方法的编译错误问题
示例代码
struct Base { void Derived(); }; struct Derived : public Base { }; int main() { Derived x; x.Derived(); // Compilation error. // gcc: Invalid use of Derived::Derived. // clang: Cannot refer to type member 'Derived' in 'Derived' with '.' return 0; }
问题
- 类T的构造函数是否会隐藏基类中同名T的方法?
- 哪条C++标准条款导致上述示例无法通过编译?
原理解误区:原本根据[class.ctor]条款认为构造函数没有名称,不会隐藏基类中的任何名称,表达式x.Derived()中的非限定名称Derived应解析为x.Base::Derived,但实际编译报错,想知道理解哪里有误。
解答
问题1:类T的构造函数是否会隐藏基类中同名T的方法?
不是构造函数在隐藏,问题根源是类名会被注入到自身的类作用域中作为类型成员,这个注入的类名隐藏了基类的同名方法。
当编译x.Derived()时,编译器优先在Derived类的作用域中查找名称Derived,这里找到的是注入到Derived类里的类名(即类型Derived本身),而非基类Base中的成员函数Derived()。由于类作用域内的同名名称会屏蔽基类的对应名称,基类的Derived()方法被隐藏,而.运算符只能访问对象的非类型成员(函数、数据成员等),无法直接访问类型成员,因此触发编译错误。
问题2:对应的C++标准条款
核心依据是以下两条标准条款:
[class.name]/2:类名会被注入到类自身的作用域中,作为一个类型成员存在。也就是说定义struct Derived后,Derived类的作用域内会存在一个名为Derived的类型成员,指代该类本身。[class.member.lookup]/1:在类作用域中查找名称时,会先在当前类的作用域内查找,找到匹配名称后就不再去基类中查找(除非使用显式限定符)。这里Derived类作用域中已有同名类型成员,因此基类Base的Derived()函数被隐藏,无法被选中。
你之前对[class.ctor]的理解是正确的——构造函数确实没有名称,不会参与名称查找,但问题的本质和构造函数无关,而是注入的类名导致的名称隐藏。
内容的提问来源于stack exchange,提问作者Igor G
相关产品推荐
相关产品推荐

