1

I want to make interface with getter which calls virtual method from child. But now i have problems: implementation of const method in child shadows parent one. Why? I have tried to make parent Get non virtual (not working). Then I have tried switch const and mutable implementation -- same behaviour. But if I implement both it seems fine.

struct A {
    virtual const int& Get() const = 0 ;

    virtual int& Get() {
        return const_cast<int&>(const_cast<const A*>(this)->Get());
    }
   virtual ~A() = default;
};

struct B : A{
    int i{42};

    const int& Get() const override { return i; }
};

int main(){

    B b;
    b.Get() = 32; // error
    static_cast<A&>(b).Get() = 32;  //ok
    std::cout << b.i;
    return 0;
}
Aj Bi
  • 11
  • 1
  • 1
    Why? Because it's the rules of C++. Shadowing is based on names not signatures. – john Jun 09 '22 at 19:28
  • A getter-type function is, by definition, is expected not to modify its object, and therefore should be `const`. – Sam Varshavchik Jun 09 '22 at 19:28
  • @john But I can implement virtual int& Get() in **B** and it will act differently. So why am i need to explicitly implement it? – Aj Bi Jun 09 '22 at 19:36
  • @AjBi I'm afraid I'm not sure what you mean. But virtual functions have the same shadowing rules as any other kind of function. – john Jun 09 '22 at 19:42
  • @SamVarshavchik it is questionable(https://stackoverflow.com/questions/856542/elegant-solution-to-duplicate-const-and-non-const-getters). We still have opportunity to do this in normal case. Why this is not working in mine? – Aj Bi Jun 09 '22 at 19:42
  • Overloading occurs among functions defined in the same scope. `B::Get` and `A::Get` are not defined in the same scope, so there is no overloading, and the only version of `Get` for `b.Get()` is the one defined in `B`. – Pete Becker Jun 09 '22 at 19:46
  • @PeteBecker In this case i should see the parent scope because inheritance is public. Or i miss something? – Aj Bi Jun 09 '22 at 20:08
  • @AjBi -- the curly braces that mark the class `A` define a scope; the curly braces that mark the class `B` define a scope. `A::Get` is in the scope defined by `A`. `B::Get` is in the scope defined by `B`. `A::Get` and `B::Get` are not defined **in the same scope**, so they do not overload. – Pete Becker Jun 09 '22 at 20:21

0 Answers0