How to hide private base class members and methods from users - c++

Maybe I didn't make my question clear, the following answers are not answering my question. Let me make the question more specific. My question is that I have a base class to send to clients so that clients can develop derived classes at their ends. How can I hide the private methods and members?
For example, in the following code snippets, the base.h file declares the base class which provides three private virtual methods for clients to override in the derived classes. The clients can override none, any, or all of them. Assuming a client developed a derived class called "Derived", and passed the "Derived" class creator to me so that I can create the Derived class somewhere, e.g. Base* p_base = new Derived() and call p_base->Execute() to actually call client implementations of virtual functions DoInitialize(), DoExecute(), DoCleanUp().
BTW: I don't think opaque pointers will work.
In Base.h file:
class Base {
public:
Base();
~Base();
void Execute();
private:
// virtual functions to be overridden by derived classes.
virtual void DoInitialize() {}
virtual void DoExecute() {}
virtual void DoCleanUp() {}
private:
// private members and functions that are intended to hide from clients
std::vector<float> data_;
....
}
In Base.cpp file
Base::Execute() {
DoInitialize();
DoExecute();
DoCleanUp();
}
In clients end
class Derived : public Base {
public:
Derived();
~Derived();
private:
// overide base class methods
void DoInitialize() {}
void DoExecute() {}
void DoCleanUp() {}
}
In my end somewhere:
void main() {
Base* p = DerivedCreater(); // creater a Derived class, assumes DerivedCreater() has passed in by clients.
p->Execute(); // I want to call the client implementation of DoInitialize(), DoExecute(), and DoCleanUp()
}

The way to go is to have an opaque pointer to the implementation.
class BaseImpl;
class Base {
public:
Base();
~Base();
private:
// virtual functions to be overridden by derived classes.
virtual void Initialize() {}
private:
// private members and functions that are not intended to override by derived classes
void Configure() { m_impl->Configure(); }
BaseImpl* m_impl;
}
Then, in the BaseImpl, you keep a pointer to the Base and you call the virtual functions as wanted. You keep BaseImpl.h in your private includes and you don't distribute it to the library users.
See:
https://en.cppreference.com/w/cpp/language/pimpl

Related

How can I use the implementation of a base class for a pure virtual method of a interface class?

I have a BASE class implementing a virtual method f(). I also have a INTERFACE class, that has a pure virtual method f(). I then have a DERIVED class that inherits both the BASE and the INTERFACE. When I try to instantiate DERIVED I get an compiler error "cannot instantiate abstract class".
class BASE
{
public:
BASE() = default;
~BASE() = default;
virtual void f(){}
};
class INTERFACE
{
public:
virtual void f() = 0;
};
class DERIVED :
public INTERFACE, public BASE
{
public:
DERIVED() = default;
~DERIVED() = default;
};
BASE class does not know INTERFACE, it is part of a library and I can not change it.
I read a few similar questions, but I could not find a clear answer as to how to solve this. What I need is to be able to instantiate DERIVED and be able to use f() from BASE in DERIVED as well as when I access it through INTERFACE.
Because the void f() of INTERFACE is never defined, BASE does not inherit from INTERFACE, so that is not an override of that function.
DERIVED does not define a void f(), so it also does not override that INTERFACE function, so that function has no body.
If you would want it to use the BASE::f to override INTERFACE::f(), either inherit BASE from INTERFACE or add an override in your DERIVED as such:
void f() override {BASE::f();}

How to prevent call to base implementation of a method

Lets say we have following hierarchy:
class Abstract
{
public:
virtual void foo() = 0;
};
class Base : public Abstract
{
public:
virtual void foo() override; //provides base implementation
};
class Derived : public Base
{
public:
virtual void foo() override; //provides derived implementation
};
If Base::foo() is ever called on the Derived object that object will desync and its data will be corrupted. It inherits Base's data structure and its manipulation but needs to perform additional operations so calling only the Base::foo() will omit these extra operations and as a result the Derived's state will be corrupted.
Therefore I would like to prevent direct call of Base implementation of foo so this:
Derived d;
d.Base::foo();
ideally, should give me a compile time error of some sorts. Or do nothing or otherwise be prevented.
However it might be I am violating the polymorphism rules and should use composition instead but that would require a lots of extra typing...
How about template method pattern:
class Abstract
{
public:
void foo() { foo_impl(); }
private:
virtual void foo_impl() = 0;
};
class Base : public Abstract
{
private:
virtual void foo_impl() override; //provides base implementation
};
class Derived : public Base
{
private:
virtual void foo_impl() override; //provides derived implementation
};
then
void test(Abstract& obj) {
obj.foo(); // the correct foo_impl() will be invoked
}
Derived d;
test(d); // impossible to call the foo_impl() of Base
You can explore the template method pattern. It allows for greater control of the execution of the methods involved.
class Abstract
{
public:
virtual void foo() = 0;
};
class Base : public Abstract
{
protected:
virtual void foo_impl() = 0;
public:
//provides base implementation and calls foo_impl()
virtual void foo() final override { /*...*/ foo_impl(); }
};
class Derived : public Base
{
protected:
virtual void foo_impl() override; //provides derived implementation
};
The pattern is seen in the iostreams library with sync() and pubsync() methods.
To prevent the direct calls and maintain the consistent state, you will need to get the final implementation of the foo method in the correct place in the stack. If the intent is to prohibit the direct call from the top of the hierarchy, then you can move the _impl methods up.
See also the non-virtual interface, the NVI pattern.
Bear in mind as well that the overriding methods do not have to have the same access specifier as the Abstract class. You could also just make the methods in the derived classes private or protected;
class Abstract
{
public:
virtual void foo() = 0;
};
class Base : public Abstract
{
virtual void foo() override; //provides base implementation
};
class Derived : public Base
{
virtual void foo() override; //provides derived implementation
};
Note: unless otherwise intended, changing the access specifier could be considered bad design - so basically if you do change the access specifier, there should should be a good reason to do so.
You can make all the foo() methods non-public, then have a non-virtual function in the Abstract class that simply calls foo.

Pure interface of a class with subclasses

Lets suppose you want to make an interface of the class Derived and it looks like this:
class Derived : public Base
{
public:
foo();
}
class Base
{
public:
tii();
//many other methods
}
How would you do the Interface? How can you make Base::tii visible (and also other methods) to this new interface?
class IDerived
{
public:
virtual foo() = 0;
// should I declare here tii() as a pure virtual function?
// but by doing it now there is ambiguity!
}
What is a good strategy?
The new Derived class should look like this....
class Derived : public Base, public IDerived
{
//implement the real thing
}
Your example is doing things backwards: the interface should be defined independently of any concrete classes with all pure virtual methods:
class IDerived
{
public:
virtual void foo() = 0;
virtual ~IDerived() {} // don't forget to include a virtual destructor
}
And the concrete classes will derive publicly from the interface:
class Derived : public Base, public IDerived
{
public:
void foo();
}
If you want IDerived to also declare methods that Derived inherits from Base, you can have Derived explicitly implement the method by calling the inherited implementation:
class Derived : public Base, public IDerived
{
public:
void foo();
void bar() { Base::bar(); }
}
At front, I dislike interfaces (they are grown by other languages than c++).
Anyway, if you have one, it should be complete: Hence have the 'tii() as a pure virtual function'. To resolve the conflict rewrite that function in 'Derived' (forward to Base::tii).

virtual inheritance query

class Base {
public:
Base(){ }
virtual void Bfun1();
virtual void Bfun2();
};
class Derv : public Base {
public:
Derv(){ }
void Dfun1();
};
Is there a difference between above definitions and the below ones ? Are they same ? if not how both are the different functionally ?
class Base {
public:
Base(){ }
void Bfun1();
void Bfun2();
};
class Derv : public virtual Base {
public:
Derv(){ }
void Dfun1();
};
They are completely different. The first set defines Bfun1 and Bfun2 as virtual function, that allows overriding them in the derived class and call those in the derived class through a base class pointer:
// assume you've overridden the functions in Derived
Base* base_ptr = new Derived;
base_ptr->Bfun1(); // will call function in derived
The second set, however, they're just normal functions. Instead, you declared the base class to be virtual, which has many implications you best read about in a good C++ book or search through the SO questions, I think we have one on that topic.

virtual function in private or protected inheritance

It's easy to understand the virtual function in public inheritance. So what's the point for virtual function in private or protected inheritance?
For example:
class Base {
public:
virtual void f() { cout<<"Base::f()"<<endl;}
};
class Derived: private Base {
public:
void f() { cout<<"Derived::f()"<<endl;}
};
Is this still called overriding? What's the use of this case? What's the relationship of these two f()?
Thanks!
Private inheritance is just an implementation technique, not an is-a relationship, as Scott Meyers explains in Effective C++:
class Timer {
public:
explicit Timer(int tickFrequency);
virtual void onTick() const; // automatically called for each tick
...
};
class Widget: private Timer {
private:
virtual void onTick() const; // look at Widget private data
...
};
Widget clients shouldn't be able to call onTick on a Widget, because that's not part of the conceptual Widget interface.
Your f() method is still overridden. This relationship is useful when implementing the Template Method design pattern. Basically, you'd implement common sets of operations in the base class. Those base class operations would then invoke a virtual method, like your f(). If the derived class overrides f(), the base class operations end up calling the derived version of f(). This allows derived classes to keep the base algorithm the same but alter the behavior to suit their needs. Here's a trivial example:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f() { cout<<"Base::f()" << endl; }
protected:
void base_foo() { f(); }
};
class DerivedOne: private Base
{
public:
void f() { cout << "Derived::f()" << endl;}
void foo() { base_foo(); }
};
class DerivedTwo: private Base
{
public:
void foo() { base_foo(); }
};
int main()
{
DerivedOne d1;
d1.foo();
DerivedTwo d2;
d2.foo();
}
Here's the result at run-time:
$ ./a.out
Derived::f()
Base::f()
Both derived classes call the same base class operation but the behavior is different for each derived class.
There doesn't need to be a point to every combination of different features. You're simply allowed to combine them.
A virtual protected member is accessible to derived classes, so it's useful to them.
A virtual private member is accessible to friend classes, so it's useful to them.
Both private and protected inheritance allow overriding virtual functions in the private/protected base class and neither claims the derived is a kind-of its base.
Protected inheritance allows derived classes of derived classes to know about the inheritance relationship and still override the virtual functions.
Privately inheriting from the Base class in your Derived class, destroys all conceptual ties between the derived and base class. The derived class is just implemented in terms of the base class, nothing more. Private inheritance is just an implementation technique and implies no relationship between the classes involved.
An example would be:
/// Thread body interface
class runnable
{
public:
virtual ~runnable() {}
virtual void run() =0;
};
/// Starts OS thread, calls p->run() in new thread
thread_id start_thread( runnable* p );
/// Has a private thread
class actor: private runnable, private noncopyable
{
private:
thread_id tid; /// private thread
public:
actor() { tid = start_thread( this ); } // here this IS-A runnable
// ...
virtual ~actor() { stop_thread( tid ); }
private:
virtual void run() { /* work */ }
};