3

I have two simple classes, and wish to access the public method stuff by passing an int value. why can't I do that with an instance of Bar? Shouldn't it inherit the public method stuff. The type hinting gives the int a parameter, but it doesn't compile.

class Foo
{
public:
    int a;
    void stuff(int a){ std::cout << a << std::endl; }
};

class Bar : public Foo
{
protected:
    void stuff() { std::cout << "hello world"; }
};



void main()
{
    Bar b
    b.stuff(3);
}
user3791372
  • 3,937
  • 3
  • 34
  • 68

4 Answers4

6

Because Bar::stuff hides Foo::stuff (only the name matters when overload resolution is performed, parameters are ignored).

You can :

  • Bring it into sope with a using declaration
  • Or alternatively, explicitly qualify the call e.g. b.Foo::stuff(3);.

Note :

  • main() must return an int.

#include <iostream>

class Foo
{
public:
    int a;
    void stuff(int a){ std::cout << a << std::endl; }
};

class Bar : public Foo
{
public:
    using Foo::stuff;
protected:
    void stuff() { std::cout << "hello world"; }
};

int main()
{
    Bar b;
    b.stuff(3);
}

Or :

int main()
{
    Bar b;
    b.Foo::stuff(3);
}
quantdev
  • 22,595
  • 5
  • 47
  • 84
4

In C++, name hiding can take place when one function in base class has the same name as one function in derived class.

Phases of the function call process

  1. Name lookup
  2. Overload resolution
  3. Access control

Name lookup stops looking for other names as soon as it finds a name in derived class Bar. Therefore, Bar::stuff() hides any function with name stuff in Foo.

After the name lookup process,

  • overload resolution fails since there is no stuff(int) in Bar.
  • even though stuff() without int parameter is called, access control fails since stuff() is protected.
Alper
  • 11,396
  • 2
  • 29
  • 36
4

When looking up the name stuff, the one in Bar found first. Once that is found, the access privileges are checked. Since Bar::stuff is protected, you are not able to use it from main.

From the draft standard:

10.2 Member name lookup [class.member.lookup]

1 Member name lookup determines the meaning of a name (id-expression) in a class scope (3.3.7). Name lookup can result in an ambiguity, in which case the program is ill-formed. For an id-expression, name lookup begins in the class scope of this; for a qualified-id, name lookup begins in the scope of the nestedname-specifier. Name lookup takes place before access control (3.4, Clause 11).

Community
  • 1
  • 1
R Sahu
  • 196,807
  • 13
  • 136
  • 247
0
b.Foo::stuff(3);

Or, you can do a trick to access any protected:)

void main()
{
    Bar b;
    class BarAccess : public Bar { friend void main(); }
    BarAccess * ba = reinterpret_cast<BarAccess *>(&b);
    ba->stuff(3);
    ba->stuff();
}
yshurik
  • 763
  • 5
  • 12