The non-virtual interface idiom describes how the virtual methods are nonpublic customisation points, and public methods are nonvirtual to allow the base class to control at all times how the customisation points are called.
This is an elegant idiom and I like to use it, but how does it work if the derived class is a base class in itself
It works, because the derived class can override a private virtual function of a base class, even if the base class function overrides its base class function.
This is perfectly legal:
class Parent
{
public:
int foo() {return bar();} // the non-virtual public interface
private
virtual int bar();
};
class Child : public Parent
{
private:
virtual int bar(); // overrides Parent::bar()
};
class Grandchild : public Child
{
private:
virtual int bar(); // overrides Child::bar();
};
The derived class can decide for itself:
You can just override the method completely by implementing the virtual function.
You can augment the method by calling the 'middle' classes function at some point in your derived class method.
If that's not what you want, you need to set it up explicitly in the 'middle' class. I wouldn't though. If you find yourself desiring this, it probably means you didn't give the base class enough customization points.
Related
I have to make a base class with one derived class in C++. In the end I need to evidence polymorphism between 2 methodes void Read and void Show.
After I did this, I have to create an abstract class Object from which the base class will be derived.This class will contain just pure virtual methods Read and Show.
I don't think I fully understand this. So I make an abstract class Object where I put these 2 methods with "=0" to mke them pure. But this means that I have to edit the base class also, to make it derived from class Object? Like, before:
class Base {
}
after
Class Base : public Object
Can someone make me understand?
You're on the right track. In your Base class, you can mark methods virtual that you intend to be polymorphic. You can set the functions = 0 if they are "pure virtual" and have no implementation in the base class, and are required in any concrete derived class.
class Base
{
public:
virtual void Read() = 0;
virtual void Show() = 0;
};
Then for your derived class you had the syntax backwards. Note that the override keyword indicates that you are overriding a virtual method from the base class. This keyword enforces that the function signature matches the one from a base class.
class Object : public Base
{
public:
void Read() override; // implement this
void Show() override; // implement this
};
The usage could look like the following. Note that you instantiate an Object but carry a pointer to a Base*. Due to polymorphism, the derived implementations are invoked.
int main()
{
Object obj;
Base* p = &obj;
p->Read(); // due to polymorphism will call Object::Read
p->Show(); // due to polymorphism will call Object::Show
}
The question is that I have multiple specialized base classes to be used by clients to develop the derived classes at clients' end. The multiple specialized base classes are all derived from the same base class. So the derived classes by clients are derived from the same base class, and the same base class pointer can be used to point all client classes. My question is how can I hide the private members and methods of base and specialized base classes from clients, and still allows the client to develop derived classes from the same base class? The very simplified codes are as follows:
In Base.h. This is the single common base of all the following specialized base classes.
class Base {
public:
Base() {}
~Base() {}
void Start();
private:
// methods to override by derived class
virtual void DoExecute() {}
private:
void Execute() {
// Do something here
DoExecute();
// Do something here
}
// Other private methods and members
}
In Base.cpp
void Base::Start() {
Execute();
}
In SpecializedBase1.h. One specialized base class for clients to derived special client class.
class SpecializedBase1 : public Base {
public:
SpecializedBase1();
~SpecializedBase1();
private:
// methods to override by derived class
virtual void DoExecute() {}
// Other private methods and members specialized for this class
}
In SpecializedBase2.h. Another specialized base class for clients to derived special client class.
class SpecializedBase2 : public Base {
public:
SpecializedBase2();
~SpecializedBase2();
private:
// methods to override by derived class
virtual void DoExecute() {}
// Other private methods and members specialized for this class
}
In clients' end, two classes are derived to be called by us.
class ClientClass1 : public SpecializedBase1 {
public:
ClientClass1();
~ClientClass1();
private:
// override base class
void DoExecute() {}
// Other private methods and members specialized for this class
}
class ClientClass2 : public SpecializedBase2 {
public:
ClientClass2();
~ClientClass2();
private:
// override base class
void DoExecute() {}
// Other private methods and members specialized for this class
}
In our end
void Main() {
typedef std::shared_ptr<Base> BasePtr;
std::vector<BasePtr> vec;
// Assume client derived classes creators are available.
vec.push_back(BasePtr(new ClientClass1()));
vec.push_back(BasePtr(new ClientClass2()));
for (auto& step : vec) {
step->Start();
}
}
BTW, this is very simplied verison. Please don't question why we have multiple specialized base classes instead of using the same base class and use pimpl, at this point, it is not possible.
A partial solution: If
you only need hidden private functions (no member variables)
and it is acceptable to make all visible members these functions need to access public
then you could provide these hidden "members" outside the class as non-members, with an explicit pointer to the object. These function can be implemented in the corresponding *.cpp files without being mentioned in the declaration, using static internal linkage or in anonymous namespace, and become completely invisible to clients.
The idea breaks, as soon as you also have private data to hide. The reason is object allocation on the stack. In that case it is the client's responsibility to provide the required memory, which therefore needs to know the object's memory layout including all private members. Impossible, if you hide them. To accomplish this, your would need heap allocation in the constructor, which boils down to PIMPL.
Consider the following base class:
class Base
{
public:
virtual ~Base(void);
virtual void foo(void);
virtual void bar(void) = 0;
}
Now suppose I know that a given class should be the most derived class of Base. Should I declare the functions virtual? The most derived class can/will be used polymorphically with Base.
For example, should I use MostDerived1 or MostDerived2?
class MostDerived1 : public Base
{
public:
~MostDerived1(void);
void foo(void);
void bar(void);
}
class MostDerived2 : public Base
{
public:
virtual ~MostDerived2(void);
virtual void foo(void);
virtual void bar(void);
}
I'm leaning towards MostDerived1 because it most closely models the intent of the programmer: I don't want another child class of MostDerived1 to be used polymorphically with MostDerived1.
Is this reasoning correct? Are there any good reasons why I should pick MostDerived2, aside from the obvious there could be a >0% chance MostDerived2 should be used polymorphically with any deriving classes (class OriginalAssumptionWrong : public MostDerived2)?
Keep in mind MostDerived1/MostDerived2 can both be used polymorphically with Base.
Adding virtual to derived classes doesn't change their behavior, MostDerived and MostDerived2 are have exactly the same behavior.
It does however document your intention, however. I would recommend it for that purpose. The override keyword also helps with this, assuming its available on your platform.
You can't turn off virtualness. Another class derived from either MostDerived1 or MostDerived2 can also override any of the virtual functions regardless of whether you omit the virtual keyword somewhere in the class hierarchy or not.
If you want to enforce that no other class derives from MostDerived1, define it as
class MostDerived1 final : public Base
{
// ...
};
The final keyword can also be used for individual virtual member functions, ensuring no derived class overrides that specific function.
Once function declear somewhere at the hierarchy as a virtual, it's virtual for ever.
You can use final or override if you using C++11
I thought of using protected constructor, but it couldn't completely solve the purpose since the class inheriting from it would be able to instantiate the base class.
As for private constructor, the derived classes too would not be instantiated.
So, any suitable technique would be appreciated.
It is unclear what you are really asking for. So let me try to clear some points:
Pure virtual functions can have definitions
If your concern is that you want to provide definitions for all of the virtual functions in your base you can provide the definitions for the pure virtual functions, and they will be available for static dispatch.
Protected grants access to your base subobject, not to every instance of base
There is a common misconception that protected allows a particular derived type accessing any instance of base. That is not true. The keyword protected grants access to the base subobject within the derived type.
class base {
protected: base() {}
};
class derived : public base {
derived() : base() { // fine our subobject
base b; // error, `b` is not your subobject
}
};
The definition of an abstract class is one that has at least one pure virtual function (virtual function-signature = 0; You can't create an abstract class without them.
Can an abstract class be implemented without pure virtual functions in C++?
If you choose the point of view from Static Polymorphism, you can do that!
An abstract base class would be simply missing a default method implementation for an interface method from the deriving class.
Additionally you can use protected constructors for those CRTP base class templates, to require inheritance for instantiation.
UPDATE:
I found a nice slide show, that explains static vs dynamic polymorphism comprehensively. Each technique has it's pros and cons and certain fields of usage, additionally you can mix both techniques (wisely of course).
To elaborate a bit, I'll give a sample:
template<class Derived>
class AbstractBase
{
public:
// Equivalent for a pure virtual function
void foo()
{
// static_cast<> enforces an 'Is a' relation from Derived to AbstractBase
static_cast<Derived*>(this)->fooImpl();
}
// Equivalent for simple virtual function (overidable from Derived)
void bar()
{
static_cast<Derived*>(this)->barImpl();
}
// Default implementation for any call to bar()
void barImpl()
{
}
protected:
AbstractBase() {}
};
// Compilation will fail, since ConcreteClass1 doesn't provide
// a declaration for fooImpl()
class ConcreteClass1
: public AbstractBase<ConcreteClass1>
{
}
// Compiles fine
class ConcreteClass2
: public AbstractBase<ConcreteClass2>
{
public:
void fooImpl()
{
// Concrete implementation ...
}
}
The following sample shows that the pattern introduced above enforces an 'Is a' relationship between abstract class and inheriting class (the template parameter)
class ConcreteClass3
{
public:
void fooImpl()
{
// Concrete implementation ...
}
}
// Instantiation will fail, because
// * the constructor is protected
// * at least the static cast will fail
AbstractBase<ConcreteClass3> instance;
I read it in my book
An abstract class is a class that is designed to be specifically used as a base class. An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier (= 0) in the declaration of a virtual member function in the class declaration.
Here is a sample of code that annoys me:
class Base {
protected:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base *b; /* Initialized by constructor, not shown here
Intended to store a pointer on an instance of any derived class of Base */
protected:
virtual void foo() { /* Some implementation */ };
virtual void foo2() {
this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */
}
};
How do you access to the protected overrided function?
Thanks for your help. :o)
Protected members in a base-class are only accessible by the current object.
Thus, you are allowed to call this->foo(), but you are not allowed to call this->b->foo(). This is independent of whether Derived provides an implementation for foo or not.
The reason behind this restriction is that it would otherwise be very easy to circumvent protected access. You just create a class like Derived, and suddenly you also have access to parts of other classes (like OtherDerived) that were supposed to be inaccessible to outsiders.
Normally, you would do it using Base::foo(), which refers to the base class of the current instance.
However, if your code needs to do it the way you're trying to and it's not allowed, then you'll need to either make foo() public or make Derived a friend of Base.
One solution would be to declare a static protected function in Base that redirects the call to the private / protected function (foo in the example).
Lets say:
class Base {
protected:
static void call_foo(Base* base) { base->foo(); }
private:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base* b;
protected:
virtual void foo(){/* Some implementation */};
virtual void foo2()
{
// b->foo(); // doesn't work
call_foo(b); // works
}
};
This way, we don't break encapsulation because the designer of Base can make an explicit choice to allow all derived classes to call foo on each other, while avoiding to put foo into the public interface or explicitly turning all possible subclasses of Base into friends.
Also, this method works regardless of whether foo is virtual or not, or whether it is private or protected.
Here is a link to a running version of the code above and here another version of the same idea with a little more business logic.
It's a bit fragile, but with the classes you defined here, won't this work?
virtual void foo2() {
reinterpret_cast<Derived *>(this->b)->foo();
}
The reinterpret_cast points at the VTABLE for the base object, and calls it through this members accessor.
You call base functions explicitly with the scope operator (Base::foo()). But in this case, the Base class doesn't define foo (it's pure virtual), so there's actually no function to execute when you say this->b->foo(); since b is a pointer to Base and not Derived.
How do you access to the protected
overrided function?
--- from where?
You can access a protected member only via inheritance (apart from the methods of the same class). Say for example you have a class Derived1 which inherits from Derived, then objects of Derived1 can call foo().
EDIT: MSDN article on protected access specifier.