It seems that it is good to make the virtual methods private in order to separate the interfaces for following two clients -
1. clients that instantiate an object and call the method
2. clients that derive from the class and may want to override the method.
Simply put - the first client does not need to know if a method is virtual. He will call the base class public non-virtual method which in turn will call the private virtual method. See code below for example.
Now in the case where the virtual method needs to super-message its base class' corresponding virtual method such as say a Save method - which has to pass through all virtual methods in the chain of inheritance in order to save data corresponding to each level of derivation - we have no option but to use a protected virtual method - unless there is a way to guarantee saving of data at all levels of derivation without using super messaging (there is none that I know).
I would like to know if above reasoning correct.
Make sure you use the scroll to see the entire code.
#include <iostream>
using namespace std;
class A {
string data;
protected:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
protected:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};
class C : public B {
string data;
protected:
virtual void SaveData() {
B::SaveData();
cout << data << endl;
}
public:
C():data("Data of C") {}
};
int main(int argc, const char * argv[])
{
C c;
c.Save();
return 0;
}
Yes, if you need to call the SaveData of another class, it needs to be accessible from that class - so public or protected.
You are exactly right:
NVI (Non-Virtual Interface) requires that virtual methods not be public
Calling the base class method requires that it not private
therefore protected is the obvious solution, at least in C++03. Unfortunately it means you have to trust the derived class developer not to forget to call "super".
In C++11, you can use final to prevent a derived class from overriding a virtual method; it means though that you are forced to introduce a new hook, example:
class Base {
public:
void save() {
// do something
this->saveImpl();
// do something
}
private:
virtual void saveImpl() {}
};
class Child: public Base {
private:
virtual void saveImpl() final {
// do something
this->saveImpl2();
// do something
}
virtual void saveImpl2() {}
};
Of course, there is the trouble of having to come up with a new name each and every time... but at least you are guaranteed that Child::saveImpl will be called because none of its children can override it.
It's difficult to tell what you're asking, but from the example, you do not need to make the method protected. It actually can be private. For details about the subtleties see this post: What is the point of a private pure virtual function?.
So long as you're not calling the private member from derived class (or outside classes), you're ok. Overriding of private members is ok. It does sound quite naughty and wrong that you can override your parent's privates, but in c++ you're allowed to do this.
The following should be ok:
#include <iostream>
using namespace std;
class A {
string data;
private:
virtual void SaveData()= 0;
public:
A():data("Data of A"){}
void Save(){
cout << data << endl;
SaveData();
}
};
class B : public A {
string data;
private:
virtual void SaveData() { cout << data << endl;}
public:
B():data("Data of B") {}
};
Related
Supposing a general player that will notify certain events to certain objects of classes. I create a base class with some virtual functions guaranteed to exist in the derived:
class PlayEventsReceiver{
virtual void StartPlay()=0;
virtual void StopPlay()=0;
};
I would derive from PlayEventsReceiver the classes interested in such "signals"
class FooPlayer:public PlayEventsReceiver{
void StartPlay(){...}
void StopPlay(){...}
};
But if I wanted, rather than inheriting, implementing the signaling mechanism as a property, like this:
class BarPlayer{
PlayEventsReceiver receiver;
};
Is it possible to implement the pure virtual functions somehow inside the class BarPlayer in a clean way and not creating intermediate derived classes?
If you don't have a derived class then the compiler has nowhere to put its functions. If you are looking for something clean then creating an explicit derived class is probably as clean as it gets.
You can't escape the fact that somewhere you need to supply the function implementations.
However, it seems you can do this anonymously by creating an unnamed class/struct. But it is not avoiding creating a derived class because an anonymous derived class is still being created:
// public interface so I use struct
struct PlayEventsReceiver {
virtual void StartPlay() = 0;
virtual void StopPlay() = 0;
};
class BarPlayer {
public:
struct : PlayEventsReceiver {
void StartPlay() override
{
std::cout << "Start Play\n";
}
void StopPlay() override
{
std::cout << "Stop Play\n";
}
} receiver;
};
int main()
{
BarPlayer bp;
bp.receiver.StartPlay();
}
I'm facing the following problem.
I implement parent Class - Vehicle, it has some derived classes, one of them - FastVehicle.
In the program I need to store a Vector of Vehicle* pointers. the pointers may point to Vehicle objects or to FastVehicle objects as well.
1) I want to be able to call the method print() for every object in the vector.
The problem is that in case of FastVehicle I also want to tranfer a parameter to the function,
I need to call a function with signature:
void print(int a)
I know a little bit about the virtual function mechanism, but according to my knowledge it works only if both functions have the same signature.
I would like to hear suggestions, about how to work it out.
2) In addition in the derived class FastVehicle has some unique function that it doesn't share with the parent class Vehicle.
It performs a task that should be performed only for FastVehicle objects.
What is the cleanest way to achieve this?
I thought maybe to implement "empty" virtual function in the parent class Vehicle and implement the "real" task inside an overriding method of FastVehicle
Maybe someone can suggest a better solution.
thanks
You can always use a dynamic_cast to cast Vehicle to FastVehicle. It returns NULL if Vehicle is not FastVehicle. It depends on your use situation if you should really do this.
for(Vehicle* vehicle : vehicleVector)
{
FastVehicle* fastVehicle = dynamic_cast<FastVehicle*>(vehicle);
if(fastVehicle)
{
fastVehicle->print(1337);
fastVehicle->somethingElse();
}
else
{
vehicle->print();
}
}
Full example available here: https://ideone.com/69n6Jb
Most likely you have to rethink why you need a parameter for FastVehicle, but not for anything other type of Vehicle. That to me is an indication of bad design.
Just declare print(int) in the base class, override it, but in the classes where you don't need the int, just disregard it.
The pragmatic solutions are:
Pass the int a parameter to the virtual print method but ignore it in Vehicle and only use it in FastVehicle
As you suggest, simply add an "empty" virtual function to the base class that is a no-op in Vehicle and is only implemented in FastVehicle
E.g:
struct Vehicle {
virtual ~Vehicle(){}
virtual void print(int /*a*/) const { std::cout << "Vehicle print\n"; }
virtual void somethingElse() { /* no-op */ }
};
struct FastVehicle : Vehicle {
void print(int a) const override {std::cout << "FastVehicle print " << a << "\n";}
void somethingElse() override { std::cout << "Something else!\n"; }
};
for (auto vehicle : vehicles) {
vehicle->print(512);
vehicle->somethingElse();
}
Live demo
Perhaps you could refactor with an abstract vehicleI:
struct vehicleI {
....
virtual void print(int) = 0;
}
and then your vehicle:
struct vehicle : vehicleI {
....
void print(int i = 0);
}
and your fastVehicle as:
struct fastvehicle: vehicleI {
....
void print(int);
}
if you want to properly use a dynamic call to a Vehicle interface, you need to define a common interface.
If you need to specify a parameter in case of FastVehicle but not in the case of FastVehicle, that's not an interface anymore.
You have two solutions:
Default parameter
struct Vehicle
{
virtual void print(int a=0) {};
};
struct FastVehicle : public Vehicle
{
void print(int a=0) override {};
};
now you can call both with or without a parameter.
Second option:
struct Vehicle
{
virtual void print() {};
};
struct FastVehicle : public Vehicle
{
void print() override {};
void setA(int a) { _a = a; }
_a{};
};
Now you can set your 'a' variable through another method, but not when you access the object through Vehicle's interface.
The Non-virtual Interface idiome (NVI) is pretty self explanatory: You don't write public virtual functions, but public functions that call a private virtual implementation function, like so:
class Object{
virtual void v_load();
public:
void load(){ v_load(); }
}
This enables you, the base class author, to check and enforce pre- and post-conditions or apply other functions so the author of deriving classes can't forget about them.
Now when you are the deriving author, you may want to write a base class yourself - let's call it Pawn - that extends on the functionality of load() and therefore has to override v_load(). But now you are facing a problem:
When you override v_load(), other clients that want to derive from your class, will always overwrite that behaviour, and they can not call Pawn::v_load() because it is a private function, neither can they call Pawn::load() because it is defined as { v_load; } in Object which will of course lead to an infinite loop. Additionally, requiring them to do so could lead to mistakes when they forget that call. If I would want them to enable that, I would have to specify the acces to v_load() as protected in Object, which seems like an ugly solution as it would weaken the encapsulation of Object greatly.
You could of course still override v_load() to call a new function v_pawnLoad(), which is then overridden by clients, but that seems very error-prone as a lot of clients will probably overload the wrong function.
So, how can I design Pawn in such a way that clients can still override v_load() while keeping the ability to check pre-conditions or call other functions and (if possible) not enabling, let alone requiring clients of Object or Pawn to call the base v_load() implementation?
If your intention is to allow people to "extend" as opposed to "replace" load's behaviour, then put the code you currently have in v_load in load then call an empty v_load in the end.
Or you could just make v_load protected if you want to let people choose between "replacing" or "extending".
If you just want to allow them to replace the behaviour, your code is fine as it is.
As a bonus, in all these 3 variants you can change "allow" with "force" by making your v_load a pure virtual if you have no default behaviour.
If you wish to limit the override to your Pawn child class, add the final keyword to v_load in Pawn and use another virtual function to allow children of Pawn to customise its behaviour.
How about mixin' in some CRTP?
#include <iostream>
class BaseObject
{
private:
virtual void v_load() = 0;
public:
void load() { v_load(); }
};
template<typename Derived>
class Object : public BaseObject
{
private:
virtual void v_load() { static_cast<Derived&>(*this).load(); }
};
class Pawn : public Object<Pawn>
{
public:
void load() { std::cout << "Pawn::load()" << std::endl; }
};
class BlackPawn : public Pawn
{
private:
virtual void v_load() {
std::cout << "BlackPawn::v_load()" << std::endl;
std::cout << "- "; Pawn::load();
}
public:
void load() {
std::cout << "BlackPawn::load()" << std::endl;
std::cout << "- "; Pawn::load();
}
};
class BigBlackPawn : public BlackPawn
{
private:
virtual void v_load() {
std::cout << "BigBlackPawn::v_load()" << std::endl;
std::cout << "- "; BlackPawn::load();
}
public:
void load() {
std::cout << "BigBlackPawn::load()" << std::endl;
std::cout << "- "; BlackPawn::load();
}
};
template<typename T>
void load(T& x)
{
x.load();
}
void vload(BaseObject& x)
{
x.load();
}
int main()
{
Pawn p;
BlackPawn bp;
BigBlackPawn bbp;
load(p);
load(bp);
load(bbp);
std::cout << std::endl;
vload(p);
vload(bp);
vload(bbp);
}
Output on ideone.
I have a design issue that I constantly keep encountering.
For the sake of illustration, let's assume that I have a polymorphic class hierarchy
class A { public: virtual ~A() {} ... };
class B: public A { ... };
class C: public B { ... };
class D: public A { ... };
...
I want to be able to print instances of these classes in a polymorphic way, i.e. each class has its own way of printing itself. The obvious way of achieving this would be to add
virtual void print(OutputStream &os) = 0;
into the base class and override this method in every subclass. However, if the original responsibility of the classes is not related to printing, this will add another responsibility to them, thus violating SRP.
My question is: what is a proper way of achieving the desired behavior without violating SRP?
In this post, a solution based on the Visitor design pattern is proposed. However, then I would need to create a class which has to know about every subclass of A. I would like to be able to add and remove subclasses without a need to always modify the visitor.
Is there some other, SRP-preserving way than the two ways described above?
There is an acyclic visitor pattern that eliminates the need to know about every subclass. It relies on dynamic_cast, but may be what you need.
There is nothing wrong with a class printing itself. It does not violate SRP because printing does not constitute a responsibility.
Remember that responsibility is defined as a reason to change. You don't change a class because your requirements for printing change. The class should only send name-value pairs to the entity responsible for printing, called the formatter. This procedure of sending name-value pairs never ever changes by itself. Any changes in it are only prompted by other changes, unrelated to printing (when you e.g. add a field, you also add its representation to the printing procedure).
The formatter should know nothing about the classes it prints, but simply present the name-value pairs according to some set of requirements. The formatter changes when the printing requirements change. Therefore printing would be the sole responsibility of the formatter.
You'll need to go for some sort of visitor of double dispatch solution in order to do this. The double dispatch approach is a bit more lightweight, so how about something like this:
In A:
class Processor
{
public:
virtual void Process(const A &a)const {}
virtual void Process(const B &b)const {}
virtual void Process(const C &c)const {}
virtual void Process(const D &d)const {}
virtual void Process(const E &e)const {}
};
In A:
class A
{
public:
virtual void Process(const Processor &processor)
{
processor.Process(*this);
}
};
Then, in each derived class override Process with an identical definition:
virtual void Process(const Processor &processor)
{
processor.Process(*this);
}
This will ensure that the correct overload in Process is called.
Now, create a stream processor:
class StreamProcessor : public Processor
{
private:
OutputStream &m_OS;
public:
StreamProcessor(OutputStream &os) : m_OS(os)
{
}
virtual void Processor(const A &a)const
{
m_os << "got a A";
}
virtual void Processor(const B &b)const
{
m_os << "got a B";
}
virtual void Processor(const C &c)const
{
m_os << "got a C";
}
// etc
};
And then:
OutputStream &operator<<(OutputStream &os, A &a)
{
PrintProcessor(os);
a.Process(PrintProcessor);
return os;
}
You can provide an interface for printing responsibility and keep common responsibilities under your class hierarchy. Example:
class Printer { public: virtual void print(OutputStream &os) = 0; }
class A { public: virtual ~A() {} ... };
class B: public A, public Printer { ... }; // this needs print function, use interface.
class C: public B { ... };
class D: public A { ... };
There probably is a fairly simple and straight-forward answer for this, but for some reason I can't see it.
I need to restrict calling methods from a class only to some methods implemented by derived classes of some interface.
Say I have
class A{
public:
static void foo();
};
class myInterface{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface{
public:
virtual void onlyCallFooFromHere()
{
A::foo(); //this should work
}
void otherFoo()
{
A::foo(); //i want to get a compilation error here
}
}
So I should be able to call A::foo only from the method onlyCallFooFromHere()
Is there a way to achieve this? I'm open to any suggestions, including changing the class design.
EDIT:
So... I feel there's a need to further explain the issue. I have a utility class which interacts with a database (mainly updates records) - class A.
In my interface (which represents a basic database objects) I have the virtual function updateRecord() from which I call methods from the db utility class. I want to enforce updating the database only in the updateRecord() function of all extending classes and nowhere else. I don't believe this to be a bad design choice, even if not possible. However, if indeed not possible, I would appreciate a different solution.
Change the class design - what you want is impossible.
I am unsure of what you are trying to achieve with so little details and I am unable to comment further.
[Disclaimer: this solution will stop Murphy, not Macchiavelli.]
How about:
class DatabaseQueryInterface {
public:
~virtual DatabseQueryInterface() = 0;
virtual Query compileQuery() const = 0; // or whatever
virtual ResultSet runQuery(const Query&) const = 0; // etc
};
class DatabaseUpdateInterface : public DatabaseQueryInterface {
public:
virtual Update compileUpdate() const = 0; // whatever
};
class DatabaseObject {
public:
virtual ~DatabaseObject() = 0;
protected:
virtual void queryRecord(const DatabaseQueryInterface& interface) = 0;
virtual void updateRecord(const DatabaseUpdateInterface& interface) = 0;
};
class SomeConcreteDatabaseObject : public DatabaseObject {
protected:
virtual void updateRecord(const DatabaseUpdateInterface& interface) {
// gets to use interface->compileUpdate()
}
virtual void queryRecord(const DatabaseQueryInterface& interface) {
// only gets query methods, no updates
}
};
So the basic idea is that your DatabaseObject base class squirrels away a private Query object and a private Update object and when it comes time to call the protected members of the subclass it hands off the Update interface to the updateRecord() method, and the Query interface to the queryRecord() method.
That way the natural thing for the subclasses is to use the object they are passed to talk to the database. Of course they can always resort to dirty tricks to store away a passed-in Update object and try to use it later from a query method, but frankly if they go to such lengths, they're on their own.
You could split your project into different TUs:
// A.h
class A
{
public:
static void foo();
};
// My.h
class myInterface
{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface
{
public:
virtual void onlyCallFooFromHere();
void otherFoo();
};
// My-with-A.cpp
#include "My.h"
#include "A.h"
void myImplementation::onlyCallFooFromHere() { /* use A */ }
// My-without-A.cpp
#include "My.h"
void myImplementation::otherFoo() { /* no A here */ }
You probably know this, but with inheritance, you can have public, protected, and private member access.
If a member is private in the base class, the derived cannot access it, while if that same member is protected, then the derived class can access it (while it still isn't public, so you're maintaining encapsulation).
There's no way to stop specific functions from being able to see whats available in their scope though (which is what you're asking), but you can design your base class so that the derived classes can only access specific elements of it.
This could be useful because class B could inherit from class A as protected (thus getting its protected members) while class C could inherit from the same class A as public (thus not getting access to its protected members). This will let you get some form of call availability difference at least -- between classes though, not between functions in the same class.
This could work.
class myInterface;
class A {
private:
friend class myInterface;
static void foo();
};
class myInterface {
public:
virtual void onlyCallFooFromHere() {callFoo();}
protected:
void callFoo() {A::foo();}
};
Though at this point I think I'd just make A::foo a static of myInterface. The concerns aren't really separate anymore.
class myInterface {
protected:
static void foo();
};
Is there a reason foo is in A?