TheMeaningfulEngineer
TheMeaningfulEngineer

Reputation: 16359

Accessing base class methods from a subclassed nested class

The question extends this question

The situation is the following. I'm extending a virtual method of a inner class:

class ClassOne {
public:
    class InnerClass {
    public:
            virtual void method1();
    protected:
        friend class ClassOne
    };    
protected:
    oftenUsedMethod();
private:
    friend class InnerClass;
};

void ClassOne::InnerClass::method1()
{
    #Do stuff with oftenUsedMethod();
}

class SubClassOne : public ClassOne {
    class DerivedInnerClass : InnerClass { 
        virtual void method1();
    };
};

void SubClassOne::DerivedInnerClass::method1()
{
    ##I need the access to the oftenUsedMethod???
}

Here is an image to try to clarify the problem :) enter image description here

InnerClass uses ofthenUsedMethod() in its methods, and has access to it. To be able to extend the methods, I need access to ofthenUsedMethod() in DerivedInnerClass. Can this be achieved?

Upvotes: 1

Views: 1251

Answers (1)

5gon12eder
5gon12eder

Reputation: 25439

There are two problems to overcome:

  1. Inner classes, by default, are not associated with an instance of the outer class, sou you'll have to make this dependency explicit by giving it a pointer to the outer class. If you do this, you'll need to be careful that instances of the inner class don't outlive the object they are referring to.
  2. The derived inner class is not derived from the outer class so it does not have access to its protected members. What you can do is add a protected function into InnerClass that calls the function. This function is a member of InnerClass and derived classes can call it. Dynamic binding will do the rest.

Here is the above in C++:

#include <iostream>

class ClassOne
{

protected:

  virtual void
  oftenUsedMethod()
  {
    std::clog << "ClassOne::oftenUsedMethod()" << std::endl;
  }

  class InnerClass
  {

  private:

    /** Pointer to an instance of the outer class. */
    ClassOne *const outer_;

  public:

    InnerClass(ClassOne *const outer) : outer_ {outer}
    {
    }

  protected:

    virtual void
    method1()
    {
      std::clog << "ClassOne::InnerClass::method1()" << std::endl;
      this->dispatch();
    }

    /**
     * Simply calls the protected member of the outer class.
     * Derived classes can therefore access it indirectly, too.
     *
     */
    void
    dispatch()
    {
      // Be aware: If *this->outer_ has already been destructed
      // (and there is no simple way for us to tell whether it has),
      // calling a member function on it will cause disaster.
      this->outer_->oftenUsedMethod();
    }
  };
};

class SubClassOne : public ClassOne
{

protected:

  virtual void
  oftenUsedMethod() override
  {
    std::clog << "SubClassOne::oftenUsedMethod()" << std::endl;
  }

  class DerivedInnerClass : public ClassOne::InnerClass
  {

    DerivedInnerClass(ClassOne *const outer) : InnerClass {outer}
    {
    }

  protected:

    virtual void
    method1() override
    {
      std::clog << "SubClassOne::DerivedInnerClass::method1()" << std::endl;
      this->dispatch();
    }
  };
};

The override is a C++11 feature, you don't need it but it makes your intention clear.

Upvotes: 1

Related Questions