virtual methods C++ - c++

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.

Related

C++ visitor pattern multiple components

I got an object tree. In the object tree I store SceneNodes. A SceneNode is usually the base class for other classes.
I want to implement different behavior for the objects that represent the SceneNodes.
The correct Pattern for this problem should be the visitor pattern. I want to iterate over the SceneNodes and want to call different functions based on the objects stored behind the SceneNodes.
But I not only want to allow one object in the object tree to be one component of the visitor pattern but to share functionality.
For example: I have a BaseObject. I can update this BaseObject (e.g. to a new position) and I can draw a BaseObject (OpenGL stuff).
But I also have a Camera object. The camera object can be updated but not drawn.
Here is the implementation of the Visitor Stuff:
class Visitor
{
public:
virtual void VisitUpdate(ComponentUpdate* element) = 0;
virtual void VisitDraw(ComponentDraw* element) = 0;
virtual void VisitOverlay(ComponentOverlay* element) = 0;
};
Visitor Component:
class Component
{
public:
virtual ~Component() { }
virtual void accept(Visitor* visitor) = 0;
};
Concrete Component:
class ComponentUpdate : public Component
{
public:
void accept(Visitor* visitor) override {
visitor->VisitUpdate(this);
}
virtual void update() = 0;
};
class ComponentDraw : public Component
{
public:
void accept(Visitor* visitor) override {
visitor->VisitDraw(this);
}
virtual void draw() = 0;
};
And finally a concrete visitor:
class SceneNodeVisitor : public Visitor
{
void VisitUpdate(ComponentUpdate* element) override {
element->update();
}
void VisitDraw(ComponentDraw* element) override {
element->draw();
}
};
Now I'd like to do something like this:
class Camera : public ComponentUpdate
{
void update() override { std::cout << "Camnera update" << std::endl; }
};
class ObjectBase : public ComponentDraw, public ComponentUpdate
{
void update() override { std::cout << "ObjectBase update" << std::endl; }
void draw() override { std::cout << "ObjectBase draw" << std::endl; }
};
Ok, so far so good. The problem I have now is that the compiler says "base class is ambiguous". I think this is not correct because ObjectBase is ambiguous because it has two different accept() functions, am I right?
Is there a way to use the visitor pattern so that I can freely anoint the classes with the functionality I need for them?
Here the main function:
int main() {
ObjectBase ob;
Camera cam;
SceneNodeVisitor visitor;
std::vector<Component*> components;
components.push_back(new Camera);
components.push_back(new ObjectBase);
components[0]->accept(&visitor);
components[1]->accept(&visitor);
}
Strange is that I can create the ObjectBase on the stack. I only get the error if I try to create the object on the heap (via new).
Pastebin is down at the moment, I can give you this example code as soon as it's up again.
Okay, I'm not entirely sure, but I think you should separate out some of the concepts you're doing.
As soon as you inherit from two classes that both inherit from the same base class, you need to start looking at virtual inheritance. That might solve your problem. But the path from ObjectBase to Component is either through ComponentDraw or ComponentUpdate. In effect, you probably have two copies of Component because you're not using virtual inheritance.
I would strongly consider using the concept of interfaces. While C++ technically doesn't have them, you can make them, anyway.
And look at virtual inheritance.

oop - C++ - Proper way to implement type-specific behavior?

Let's say I have a parent class, Arbitrary, and two child classes, Foo and Bar. I'm trying to implement a function to insert any Arbitrary object into a database, however, since the child classes contain data specific to those classes, I need to perform slightly different operations depending on the type.
Coming into C++ from Java/C#, my first instinct was to have a function that takes the parent as the parameter use something like instanceof and some if statements to handle child-class-specific behavior.
Pseudocode:
void someClass(Arbitrary obj){
obj.doSomething(); //a member function from the parent class
//more operations based on parent class
if(obj instanceof Foo){
//do Foo specific stuff
}
if(obj instanceof Bar){
//do Bar specific stuff
}
}
However, after looking into how to implement this in C++, the general consensus seemed to be that this is poor design.
If you have to use instanceof, there is, in most cases, something wrong with your design. – mslot
I considered the possibility of overloading the function with each type, but that would seemingly lead to code duplication. And, I would still end up needing to handle the child-specific behavior in the parent class, so that wouldn't solve the problem anyway.
So, my question is, what's the better way of performing operations that where all parent and child classes should be accepted as input, but in which behavior is dictated by the object type?
First, you want to take your Arbitrary by pointer or reference, otherwise you will slice off the derived class. Next, sounds like a case of a virtual method.
void someClass(Arbitrary* obj) {
obj->insertIntoDB();
}
where:
class Arbitrary {
public:
virtual ~Arbitrary();
virtual void insertIntoDB() = 0;
};
So that the subclasses can provide specific overrides:
class Foo : public Arbitrary {
public:
void insertIntoDB() override
// ^^^ if C++11
{
// do Foo-specific insertion here
}
};
Now there might be some common functionality in this insertion between Foo and Bar... so you should put that as a protected method in Arbitrary. protected so that both Foo and Bar have access to it but someClass() doesn't.
In my opinion, if at any place you need to write
if( is_instance_of(Derived1) )
//do something
else if ( is_instance_of(Derived2) )
//do somthing else
...
then it's as sign of bad design. First and most straight forward issue is that of "Maintainence". You have to take care in case further derivation happens. However, sometimes it's necessary. for e.g if your all classes are part of some library. In other cases you should avoid this coding as far as possible.
Most often you can remove the need to check for specific instance by introducing some new classes in the hierarchy. For e.g :-
class BankAccount {};
class SavingAccount : public BankAccount { void creditInterest(); };
class CheckingAccount : public BankAccount { void creditInterest(): };
In this case, there seems to be a need for if/else statement to check for actual object as there is no corresponsing creditInterest() in BanAccount class. However, indroducing a new class could obviate the need for that checking.
class BankAccount {};
class InterestBearingAccount : public BankAccount { void creditInterest(): } {};
class SavingAccount : public InterestBearingAccount { void creditInterest(): };
class CheckingAccount : public InterestBearingAccount { void creditInterest(): };
The issue here is that this will arguably violate SOLID design principles, given that any extension in the number of mapped classes would require new branches in the if statement, otherwise the existing dispatch method will fail (it won't work with any subclass, just those it knows about).
What you are describing looks well suited to inheritance polymorphicism - each of Arbitrary (base), Foo and Bar can take on the concerns of its own fields.
There is likely to be some common database plumbing which can be DRY'd up the base method.
class Arbitrary { // Your base class
protected:
virtual void mapFields(DbCommand& dbCommand) {
// Map the base fields here
}
public:
void saveToDatabase() { // External caller invokes this on any subclass
openConnection();
DbCommand& command = createDbCommand();
mapFields(command); // Polymorphic call
executeDbTransaction(command);
}
}
class Foo : public Arbitrary {
protected: // Hide implementation external parties
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Foo specific fields here
}
}
class Bar : public Arbitrary {
protected:
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Bar specific fields here
}
}
If the base class, Arbitrary itself cannot exist in isolation, it should also be marked as abstract.
As StuartLC pointed out, the current design violates the SOLID principles. However, both his answer and Barry's answer has strong coupling with the database, which I do not like (should Arbitrary really need to know about the database?). I would suggest that you make some additional abstraction, and make the database operations independent of the the data types.
One possible implementation may be like:
class Arbitrary {
public:
virtual std::string serialize();
static Arbitrary* deserialize();
};
Your database-related would be like (please notice that the parameter form Arbitrary obj is wrong and can truncate the object):
void someMethod(const Arbitrary& obj)
{
// ...
db.insert(obj.serialize());
}
You can retrieve the string from the database later and deserialize into a suitable object.
So, my question is, what's the better way of performing operations
that where all parent and child classes should be accepted as input,
but in which behavior is dictated by the object type?
You can use Visitor pattern.
#include <iostream>
using namespace std;
class Arbitrary;
class Foo;
class Bar;
class ArbitraryVisitor
{
public:
virtual void visitParent(Arbitrary& m) {};
virtual void visitFoo(Foo& vm) {};
virtual void visitBar(Bar& vm) {};
};
class Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Parent specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitParent(*this);
}
};
class Foo: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Foo specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitFoo(*this);
}
};
class Bar: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Bar specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitBar(*this);
}
};
class SetArbitaryVisitor : public ArbitraryVisitor
{
void visitParent(Arbitrary& vm)
{
vm.DoSomething();
}
void visitFoo(Foo& vm)
{
vm.DoSomething();
}
void visitBar(Bar& vm)
{
vm.DoSomething();
}
};
int main()
{
Arbitrary *arb = new Foo();
SetArbitaryVisitor scv;
arb->accept(scv);
}

c++ overriding a function only for a specific instance

I was wondering whether there's a way to override a function for a specific instance only. For ex,
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
Is there a way to achieve this?
I think virtual function is just what you want, with virtual function, different instances of the same type can have different functions, but you need to inherit the base class. for example
class A
{
public:
...
virtual void update()
{
std::cout << "Class A\n";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class B\n";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class C\n";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
each instance in the above code will bind different update functions.
Besides, you can also use function pointer to implement your requirement, but it is not recommended. For example
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update A\n";
}
void b_update()
{
std::cout << "update B\n";
}
void c_update()
{
std::cout << "update C\n";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
Hope helps!
Hold a function in the class.
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
You may have noticed that the end brace of a class is often followed by a semicolon, whereas the end braces of functions, while loops etc don't. There's a reason for this, which relates to a feature of struct in C. Because a class is almost identical to a struct, this feature exists for C++ classes too.
Basically, a struct in C may declare a named instance instead of (or as well as) a named "type" (scare quotes because a struct type in C isn't a valid type name in itself). A C++ class can therefore do the same thing, though AFAIK there may be severe limitations on what else that class can do.
I'm not in a position to check at the moment, and it's certainly not something I remember using, but that may mean you can declare a named class instance inheriting from a base class without giving it a class name. There will still be a derived type, but it will be anonymous.
If valid at all, it should look something like...
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
Personally, even if this is valid, I'd avoid using it for a number of reasons. For example, the lack of a class name means that it's not possible to define member functions separately. That means that the whole class declaration and definition must go where you want the instance declared - a lot of clutter to drop in the middle of a function, or even in a list of global variables.
With no class name, there's presumably no way to declare a constructor or destructor. And if you have non-default constructors from the base class, AFAIK there's no way to specify constructor parameters with this.
And as I said, I haven't checked this - that syntax may well be illegal as well as ugly.
Some more practical approaches to varying behaviour per-instance include...
Using dependency injection - e.g. providing a function pointer or class instance (or lambda) for some part of the behavior as a constructor parameter.
Using a template class - effectively compile-time dependency injection, with the dependency provided as a function parameter to the template.
I think it will be the best if you'll tell us why do you need to override a function for a specific instance.
But here's another approach: Strategy pattern.
Your class need a member that represent some behaviour. So you're creating some abstract class that will be an interface for different behaviours, then you'll implement different behaviours in subclasses of that abstract class. So you can choose those behaviours for any object at any time.
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
You can use local classes, yet, personally, I consider the "hold function in the class" approach mentioned in the other answer better. I'd recommend the following approach only if doFunc must access internals of your base class, which is not possible from a function held in a member variable:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
From a design patterns point of view, the "local classes" approach implements the template method pattern, while the "hold a function(al) in a member variable" approach reflects the strategy pattern. Which one is more appropriate depends on what you need to achieve.

C++: Adding methods to a polymorphic class hierarchy without violating SRP?

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 { ... };

Enforcing correct parameter types in derived virtual function

I'm finding it difficult to describe this problem very concisely, so I've attached the code for a demonstration program.
The general idea is that we want a set of Derived classes that are forced to implement some abstract Foo() function from a Base class. Each of the derived Foo() calls must accept a different parameter as input, but all of the parameters should also be derived from a BaseInput class.
We see two possible solutions so far, neither we're very happy with:
Remove the Foo() function from the base class and reimplement it with the correct input types in each Derived class. This, however, removes the enforcement that it be implemented in the same manner in each derived class.
Do some kind of dynamic cast inside the receiving function to verify that the type received is correct. However, this does not prevent the programmer from making an error and passing the incorrect input data type. We would like the type to be passed to the Foo() function to be compile-time correct.
Is there some sort of pattern that could enforce this kind of behaviour? Is this whole idea breaking some sort of fundamental idea underlying OOP? We'd really like to hear your input on possible solutions outside of what we've come up with.
Thanks so much!
#include <iostream>
// these inputs will be sent to our Foo function below
class BaseInput {};
class Derived1Input : public BaseInput { public: int d1Custom; };
class Derived2Input : public BaseInput { public: float d2Custom; };
class Base
{
public:
virtual void Foo(BaseInput& i) = 0;
};
class Derived1 : public Base
{
public:
// we don't know what type the input is -- do we have to try to cast to what we want
// and see if it works?
virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }
// prefer something like this, but then it's not overriding the Base implementation
//virtual void Foo(Derived1Input& i) { std::cout << "Derived1 did something with Derived1Input..." << std::endl; }
};
class Derived2 : public Base
{
public:
// we don't know what type the input is -- do we have to try to cast to what we want
// and see if it works?
virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }
// prefer something like this, but then it's not overriding the Base implementation
//virtual void Foo(Derived2Input& i) { std::cout << "Derived2 did something with Derived2Input..." << std::endl; }
};
int main()
{
Derived1 d1; Derived1Input d1i;
Derived2 d2; Derived2Input d2i;
// set up some dummy data
d1i.d1Custom = 1;
d2i.d2Custom = 1.f;
d1.Foo(d2i); // this compiles, but is a mistake! how can we avoid this?
// Derived1::Foo() should only accept Derived1Input, but then
// we can't declare Foo() in the Base class.
return 0;
}
Since your Derived class is-a Base class, it should never tighten the base contract preconditions: if it has to behave like a Base, it should accept BaseInput allright. This is known as the Liskov Substitution Principle.
Although you can do runtime checking of your argument, you can never achieve a fully type-safe way of doing this: your compiler may be able to match the DerivedInput when it sees a Derived object (static type), but it can not know what subtype is going to be behind a Base object...
The requirements
DerivedX should take a DerivedXInput
DerivedX::Foo should be interface-equal to DerivedY::Foo
contradict: either the Foo methods are implemented in terms of the BaseInput, and thus have identical interfaces in all derived classes, or the DerivedXInput types differ, and they cannot have the same interface.
That's, in my opinion, the problem.
This problem occured to me, too, when writing tightly coupled classes that are handled in a type-unaware framework:
class Fruit {};
class FruitTree {
virtual Fruit* pick() = 0;
};
class FruitEater {
virtual void eat( Fruit* ) = 0;
};
class Banana : public Fruit {};
class BananaTree {
virtual Banana* pick() { return new Banana; }
};
class BananaEater : public FruitEater {
void eat( Fruit* f ){
assert( dynamic_cast<Banana*>(f)!=0 );
delete f;
}
};
And a framework:
struct FruitPipeLine {
FruitTree* tree;
FruitEater* eater;
void cycle(){
eater->eat( tree->pick() );
}
};
Now this proves a design that's too easily broken: there's no part in the design that aligns the trees with the eaters:
FruitPipeLine pipe = { new BananaTree, new LemonEater }; // compiles fine
pipe.cycle(); // crash, probably.
You may improve the cohesion of the design, and remove the need for virtual dispatching, by making it a template:
template<class F> class Tree {
F* pick(); // no implementation
};
template<class F> class Eater {
void eat( F* f ){ delete f; } // default implementation is possible
};
template<class F> PipeLine {
Tree<F> tree;
Eater<F> eater;
void cycle(){ eater.eat( tree.pick() ); }
};
The implementations are really template specializations:
template<> class Tree<Banana> {
Banana* pick(){ return new Banana; }
};
...
PipeLine<Banana> pipe; // can't be wrong
pipe.cycle(); // no typechecking needed.
You might be able to use a variation of the curiously recurring template pattern.
class Base {
public:
// Stuff that don't depend on the input type.
};
template <typename Input>
class Middle : public Base {
public:
virtual void Foo(Input &i) = 0;
};
class Derived1 : public Middle<Derived1Input> {
public:
virtual void Foo(Derived1Input &i) { ... }
};
class Derived2 : public Middle<Derived2Input> {
public:
virtual void Foo(Derived2Input &i) { ... }
};
This is untested, just a shot from the hip!
If you don't mind the dynamic cast, how about this:
Class BaseInput;
class Base
{
public:
void foo(BaseInput & x) { foo_dispatch(x); };
private:
virtual void foo_dispatch(BaseInput &) = 0;
};
template <typename TInput = BaseInput> // default value to enforce nothing
class FooDistpatch : public Base
{
virtual void foo_dispatch(BaseInput & x)
{
foo_impl(dynamic_cast<TInput &>(x));
}
virtual void foo_impl(TInput &) = 0;
};
class Derived1 : public FooDispatch<Der1Input>
{
virtual void foo_impl(Der1Input & x) { /* your implementation here */ }
};
That way, you've built the dynamic type checking into the intermediate class, and your clients only ever derive from FooDispatch<DerivedInput>.
What you are talking about are covariant argument types, and that is quite an uncommon feature in a language, as it breaks your contract: You promised to accept a base_input object because you inherit from base, but you want the compiler to reject all but a small subset of base_inputs...
It is much more common for programming languages to offer the opposite: contra-variant argument types, as the derived type will not only accept everything that it is bound to accept by the contract, but also other types.
At any rate, C++ does not offer contravariance in argument types either, only covariance in the return type.
C++ has a lot of dark areas, so it's hard to say any specific thing is undoable, but going from the dark areas I do know, without a cast, this cannot be done. The virtual function specified in the base class requires the argument type to remain the same in all the children.
I am sure a cast can be used in a non-painful way though, perhaps by giving the base class an Enum 'type' member that is uniquely set by the constructor of each possible child that might possibly inherit it. Foo() can then check that 'type' and determine which type it is before doing anything, and throwing an assertion if it is surprised by something unexpected. It isn't compile time, but it's the closest a compromise I can think of, while still having the benefits of requiring a Foo() be defined.
It's certainly restricted, but you can use/simulate coviarance in constructors parameters.