2

How can I possibly do this:

class Base
{
public:
    int a, b, c;
    void function();
    ...
};

class Derived1 : 
    private Base
{
public:
    int d, e, f;
    ...
};

class Derived2 :
    private Base
{
public:
    void addObject(const Base* obj);
    ...
};

Note that I inherit it as private


Then I would like to do like:

Base* d1 = new Derived1();
Base* d2 = new Derived2();

d2->addObject(d1);

And here is the relevant issue I am getting from the compiler:

C:\test\test.cpp||In function 'void init()':|
C:\test\test.cpp|423|error: no matching function for call to 'Derived2::addObject(const Base*)'|
C:\test\test.cpp|423|note: candidate is:|
C:\test\test.h|29|note: void Derived2::addObject(const Base*)|
C:\test\test.h|29|note:   no known conversion for argument 1 from 'Derived1 {aka ... }' to 'const Base* {aka ... }'|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 9 seconds) ===|

The reason I want to inherit the Base as private by some derived classes is to hide some Base's members/functions in public scope.

I do not want to directly access some Base::functions() in a public scope but else, used a Derived::function() instead to manipulate its data members and let the derived class decide what action it would perform.

However, I could think of overriding each function from base class that I do not want to modify directly in public scope but its not flexible and too many in my case.

What I mean is:

class Base
{
public:
    //I must think in advance deciding whether if it'll be virtual or not.
    [virtual] void f1(int);
    [virtual] void f2(int);
    [virtual] void f3(int);
    //and many more...
};

class Derivedn :
    private Base
{
public:
    //hmm, I should not neglect to override certain base' member functions
    //that I don't want to access in public scope.
    void f1(int);
};

I want to avoid this but...

Is there any other way I can do, similar to this one, without overriding each Base::function()s?

mr5
  • 3,438
  • 3
  • 40
  • 57

3 Answers3

4

The reason this does not work is that inheriting privately does not constitute an "is a" relationship. In fact, is a lot closer to composition than inheritance, because the derived class acquires the implementation of the base without acquiring its interface.

The reason I want to inherit the Base as private by some derived classes is to hide some Base's members/functions in public scope.

That is a wrong reason to inherit privately. Here are some good answers to the question when you should inherit privately.

Is there any other way I can do, similar to this one, without overriding each Base::function()s?

You are not required to override every single one of the Base's functions, unless they are pure virtual (also known as "abstract") ones. Your base class can provide empty implementations for its virtual functions, so that the derived classes could decide which functionality to provide.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Of course I do not want to inherit every `Base::functions()` on every derived classes, but in my case of implementation, I should be careful w/c of `Base::function()` I must override when a certain functions should perform in public scope. Since that I can do this, I think its not a good choice in my case. – mr5 Nov 29 '13 at 02:58
  • @mr5 Note that you can selectively make some of the inherited functions private ([demo](http://ideone.com/G8uvR5)). – Sergey Kalinichenko Nov 29 '13 at 03:08
  • I really like to make the inheritance private so I can avoid too much `function overriding`s. However if I did this, I cannot do the `d2->addObject(d1);` thing. Also thinking in advance, deciding, whether making the `base member function` to be declared as `virtual` or not seems a problem to me. – mr5 Nov 29 '13 at 03:20
  • @mr5 You should make them all virtual: once you add the first virtual function, there is very little overhead to add more virtual functions, be it ten more or a hundred more. – Sergey Kalinichenko Nov 29 '13 at 03:24
  • Then I would end up in reimplementing it again and again, adding only a couple lines of codes for checking and some adjustments. – mr5 Nov 29 '13 at 03:27
  • @mr5 If you like the base class implementation, you can keep it without overriding. You can also call the base implementation from your own if you want to add just a few more checks. – Sergey Kalinichenko Nov 29 '13 at 03:31
  • Well, I was thinking of: I just like this certain function to be called from derived class but don't let other `base function` be called. That summarizes my problem. Having to re-implement/override base function w/ few modification won't make much sense in my case. – mr5 Nov 29 '13 at 03:40
  • 1
    @mr5 Inheriting privately wouldn't give you a way to selectively tell which functions should be available to which derived classes. C++ access control does not have such a fine level of granularity. – Sergey Kalinichenko Nov 29 '13 at 03:44
0

I think your code should read:

d2.addObject(&d1); // Note the "&"

As the compiler says, there is no possible conversion from an instance of Derived1 to a const pointer to an instance of Base.

DrFred
  • 1
  • 1
0

Not sure what you wanna, but polymorphism do exactly that, allow you to override a base function in Derived class:

class Base
{
public:
    int a, b, c;
    virtual void function();
    ^^^^^^^
    ...
};

class Derived1 : 
    public Base
{
public:
    int d, e, f;
    virtual void function(); // do derived version of Base::function
};

and now you can access Derived version of function from Base objects

Amadeus
  • 10,199
  • 3
  • 25
  • 31