Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a method be referenced using a child class name in C++?

Please consider a struct A with a method f, and an inherited struct B, which does not redefine f. In this case B::f refers to the same method as A::f.

Is it allowed to invoke the method f of an A object using B::f name as in the following example?

struct A { void f() {} };
struct B : A {};
int main() { A{}.B::f(); }

Clang and GCC diverge here. Clang is fine with the program, while GCC prints the error:

error: 'B' is not a base of 'A'

demo: https://gcc.godbolt.org/z/Pn7jehzdP

Which compiler is right here according to the standard?

like image 508
Fedor Avatar asked Aug 25 '21 15:08

Fedor


People also ask

Can we call child class method in parent class?

No you can't. The annotation Override is optional, thus even not explicitly declaring it on child class' method, it will automatically override the parent version of the method.

Can class and function have same name?

Yes, It is allowed to define a method with the same name as that of a class. There is no compile-time or runtime error will occur.


2 Answers

GCC is correct: [class.access.base]/6 requires that a pointer to the left-hand operand of . be able to be

implicitly converted to a pointer to the naming class of the right operand.

The term "naming class" is defined in [class.access.general]/5; in your example it is B, and obviously an A* cannot be implicitly converted to a B*.

The placement of the rule is counterintuitive for this particular case that has no non-public members or inheritance.

like image 194
Davis Herring Avatar answered Oct 21 '22 14:10

Davis Herring


Is it allowed to invoke the method f of an A object using B::f name as in the following example?

struct A { void f() {} };

struct B : A {};

int main() { A{}.B::f(); }

A{}.B::f() tries to build an object of type A. Then call its member B::f This the error, because A knows nothing about B.

If you want to call a base member from a derived class them normally you just use D d; d.f();

In your case, use B{}.A::f()
Be aware that calling a base method like this will break virtual ways.

like image 27
Ripi2 Avatar answered Oct 21 '22 15:10

Ripi2