Home > Net >  C override of nested class function
C override of nested class function

Time:09-01

I have a class that derives from a base class, which has a nested class. I want to override a nested class's member function in my derived class and override a base class's member function. (as shown below)

I found a solution (https://stackoverflow.com/a/11448927/13147242) that works by creating another nested class that inherits from the base class's nested class. But when creating an instance of this new nested class I get another return type, which doesn't help me because the function that I want to override that returns a base's nested class object, but should access the nested's override function.

A code example of that setup looks like this:


class Base {
public:
  class Nested {
    friend class Derived;

  public:
    virtual void funcNested() { std::cout << "funcNested()" << std::endl; }
  };

  virtual Nested funcBase() {
    std::cout << "funcBase()" << std::endl;
    Nested tmp;
    tmp.funcNested();
    return tmp;
  }
};

class Derived : public Base {
public:
  // I want to override this function without creating another nested class that derives from Nested, i.e.
  // void Base::Nested::funcNested() override { /* ... */ }

  // the mentioned solution does it like this:
  class DerivedNested : public Base::Nested {
  public:
    void funcNested() override { std::cout << "override funcNested()" << std::endl; }
  };

  // but then I can't override this function in a way that the nested function is called
  Nested funcBase() override {
    std::cout << "override funcBase()" << std::endl;
    return DerivedNested();
  }
};


int main() {
  Derived derived;
  Base::Nested nested = derived.funcBase();
  nested.funcNested();

  return 0;
}

Then the output here is:

override funcBase()
funcNested()

but I want to have:

override funcBase()
override funcNested()

Is this possible?

CodePudding user response:

It appears the issue is that in this line Base::Nested nested = derived.funcBase(); a copy of type Nested is created by a Nested::Nested(Nested&) copy constructor, out of derived object (DerivedNested). Then in nested.funcNested(); line a method is called on that copy object of parent class, thus no dynamic dispatch here.

As described in this answer of the similar question, you should use reference/smart pointer to prevent creating a copy of the base class. Like:

#include <memory>

class Base {
public:
  class Nested {
    friend class Derived;

  public:
    virtual void funcNested() { std::cout << "funcNested()" << std::endl; }
  };

  virtual std::shared_ptr<Nested> funcBase() {
    std::cout << "funcBase()" << std::endl;
    Nested tmp;
    tmp.funcNested();
    return std::make_shared<Nested>(tmp);
  }
};

class Derived : public Base {
public:
  class DerivedNested : public Base::Nested {
  public:
    virtual void funcNested() override { std::cout << "override funcNested()" << std::endl; }
  };

  std::shared_ptr<Nested> funcBase() override {
    std::cout << "override funcBase()" << std::endl;
    DerivedNested tmp;
    tmp.funcNested();
    return std::make_shared<DerivedNested>(tmp);
  }
};

int main() {
    Derived derived; 
    auto nested = derived.funcBase(); 
    nested->funcNested();

    return 0;
}
  • Related