lundi 28 novembre 2022

When inheriting a Base class privately, can I declare the Base classes Basse class public?

I have a class "SuperBase" with public methods and a class "Base", that derives from SuperBase, also with public methods. I cannot alter these, as they come from an external project.

I want my own class "Derived" to inherit privately from Base, but still keep SuperBase public.

External Code (cannot be changed):

class SuperBase
{
public:
   void printSuperBase() const
   {
      std::cout << "Super Base Class\n";
   }
};

class Base : public SuperBase
{
public:
   void print() const
   {
      std::cout << "Base Class\n";
   }
};

My own code (can be changed):

class Derived: private Base
{
public:
   void print() const
   {
      std::cout << "Derived Class\n";
   }
};

void function(SuperBase const& sb)
{
   sb.printSuperBase();
}


int main() 
{
   Derived D{};
   D.print();    //prints "Derived Class\n"
   function(D);  //cannot access SuperBase, as Base was included privately
}

Note that I cannot override any of the Base class methods, as they are not declared virtual.

Including both, Base and SuperBase does not work as this makes SuperBase ambiguous.

class Derived: private Base, public SuperBase
{
public:
   void print() const
   {
      std::cout << "Derived Class\n";
   }
};

void function(SuperBase const& sb)
{
   sb.printSuperBase();
}


int main() 
{
   Derived D{};
   D.print();    //prints "Derived Class\n"
   function(D);  //base class SuperBase is ambiguous
}

Including Base publicly and declaring it's methods as private does not work either, as I now can pass Derived to functions using Base, that can access all privately declared methods

class Derived: public Base
{
public:
   void print() const
   {
      std::cout << "Derived Class\n";
   }
private:
   using Base::print; //declare base method private to make it inaccessible
};

void function2(Base const& b)
{
   b.print();          //prints "Base Class\n", but shall be inaccessible instead.
   b.printSuperBase();
}


int main() 
{
   Derived D{};
   D.print();    //prints "Derived Class\n"
   function2(D); //D gets passed as Base class, but shall not be allowed
}

Aucun commentaire:

Enregistrer un commentaire