简体   繁体   中英

C++ inheritance name hiding

I have an issue with C++ and inheritance. Hopefully someone can clear this up for me.

The following code compiles and runs:

struct Foo {
  virtual ~Foo() {}
  virtual unsigned int rnd1() = 0;
  unsigned int rnd2(unsigned int limit) {
    return rnd1() % limit;
  }
};

struct Bar : public Foo {
  Bar() : state(12345678) {}
  unsigned int rnd1() {
    return state = state * 1664525 + 1013904223;
  }
 private:
  int state;
};

#include <cstdio>

void fooTest() {
  Foo* r = new Bar();
  printf("Foo->rnd2(16) = %u\n", r->rnd2(16));
  delete r;
}

void barTest() {
  Bar* r = new Bar();
  printf("Bar->rnd2(16) = %u\n", r->rnd2(16));
  delete r;
}

int main() {
  fooTest();
  barTest();
}

There is no issues here because rnd1 and rnd2 have different names. If rnd1 and rnd2 are both renamed to rnd it no longer compiles. The following code doesn't compile:

struct Foo {
  virtual ~Foo() {}
  virtual unsigned int rnd() = 0;
  unsigned int rnd(unsigned int limit) {
    return rnd() % limit;
  }
};

struct Bar : public Foo {
  Bar() : state(12345678) {}
  unsigned int rnd() {
    return state = state * 1664525 + 1013904223;
  }
 private:
  int state;
};

#include <cstdio>

void fooTest() {
  Foo* r = new Bar();
  printf("Foo->rnd(16) = %u\n", r->rnd(16));
  delete r;
}

void barTest() {
  Bar* r = new Bar();
  printf("Bar->rnd(16) = %u\n", r->rnd(16));
  delete r;
}

int main() {
  fooTest();
  barTest();
}

Here is the error from gcc:

ubuntu:~$ g++ -Wall -Wextra -pedantic test.cpp 
test.cpp: In function ‘void barTest()’:
test.cpp:28:42: error: no matching function for call to ‘Bar::rnd(int)’
    printf("Bar->rnd(16) = %u\n", r->rnd(16));
                                      ^
test.cpp:28:42: note: candidate is:
test.cpp:11:16: note: virtual unsigned int Bar::rnd()
    unsigned int rnd() {
            ^
test.cpp:11:16: note:   candidate expects 0 arguments, 1 provided

My questions is: why doesn't C++ use the parameters as part of the name? It does this is so many other situation, why not now?

Just kindly ask it if you really mean it. Add declaration

using Foo::rnd;

to the public section of Bar .

By default if you provide a method under some name, methods of the same name but different signatures are hidden. This is because such situation often occurs by mistake when you intend to override, but use incorrect signature and if it happens, it would be difficult to detect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM