Related
Today interviewer told me that Visitor pattern & double dispatch can be used to call non-virtual method of derived class from 3rd party library which source code can't be accessed/changed (this is what they do in their production code, he said).
For example, in below code they pass reference to Animal into Bar and call specific methods of classes derived from Animal without using dynamic_cast. Point is that dynamic_cast isn't used anywhere in their implementation. Templates aren't used.
I did rephrased my question to interviewer few times so there's no misunderstanding.
I don't see a way implementing Visitor without adding Accept method to classes in library that will utilize argument overloading on Visitor::Visit by passing *this to it.
Is this possible? Or interviewer confused it with other language that probably allow something C++ doesn't? Because he was emphasizing that Visitor and double dispatch is used together, whereas AFAIK in C++ double dispatch is Visitor, meaning Visitor is used to implement double dispatch. I hope I didn't lost you. Thanks for your time!
import <iostream>;
namespace LibraryCode // can't be changed
{
class Animal
{
public:
virtual ~Animal() = default;
public:
virtual void move() const { std::cout << "Animal: moving!" << std::endl; };
void breath() const { std::cout << "Animal: breathing!" << std::endl; }
};
class Duck : public Animal
{
public:
void move() const override { std::cout << "Duck: flying!" << std::endl; }
void make_nest() const { std::cout << "Duck: making nest!" << std::endl; }
};
class Dolphin : public Animal
{
public:
void move() const override { std::cout << "Dolphin: swimming!" << std::endl; }
void make_air_bubble() const { std::cout << "Dolphin: making air bubble!" << std::endl; }
};
}
void Bar(LibraryCode::Animal const& a)
{
a.breath();
a.move();
// w/o using dynamic_cast call make_nest if it's a Duck
// w/o using dynamic_cast call make_air_bubble if it's a Dolphin
}
int main()
{
Bar(LibraryCode::Duck{});
Bar(LibraryCode::Dolphin{});
}
I've a parent class with 2 or more child class deriving from it. The number of different child classes may increase in future as more requirements are presented, but they'll all adhere to base class scheme and will contain few unique methods of their own. Let me present an example -
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class B{
private: int a; int b;
public: B(const int _a, const int _b) : a(_a), b(_b){}
virtual void tell(){ std::cout << "BASE" << std::endl; }
};
class C : public B{
std::string s;
public: C(int _a, int _b, std::string _s) : B(_a, _b), s(_s){}
void tell() override { std::cout << "CHILD C" << std::endl; }
void CFunc() {std::cout << "Can be called only from C" << std::endl;}
};
class D : public B{
double d;
public: D(int _a, int _b, double _d) : B(_a, _b), d(_d){}
void tell() override { std::cout << "CHILD D" << std::endl; }
void DFunc() {std::cout << "Can be called only from D" << std::endl;}
};
int main() {
std::vector<std::unique_ptr<B>> v;
v.push_back(std::make_unique<C>(1,2, "boom"));
v.push_back(std::make_unique<D>(1,2, 44.3));
for(auto &el: v){
el->tell();
}
return 0;
}
In the above example tell() method would work correctly since it is virtual and overrided properly in child classes. However for now I'm unable to call CFunc() method and DFunc() method of their respective classes. So I've two options in my mind -
either packup CFunc() and friends inside some already defined virtual method in child class so that it executes together. But I'll loose control over particular execution of unique methods as their number rises.
or provide some pure virtual methods in base class, which would be like void process() = 0 and let them be defined in child classes as they like. Would be probably left empty void process(){} by some and used by some. But again it doesn't feels right as I've lost return value and arguments along the way. Also like previous option, if there are more methods in some child class, this doesn't feels right way to solve.
and another -
dynamic_cast<>?. Would that be a nice option here - casting back parent's pointer to child's pointer (btw I'm using smart pointers here, so only unique/shared allowed) and then calling the required function. But how would I differentiate b/w different child classes? Another public member that might return some unique class enum value?
I'm quite unexperienced with this scenario and would like some feedback. How should I approach this problem?
I've a parent class with 2 or more child class deriving from it... But I'll loose control over particular execution of unique methods as their number rises.
Another option, useful when the number of methods is expected to increase, and the derived classes are expected to remain relatively stable, is to use the visitor pattern. The following uses boost::variant.
Say you start with your three classes:
#include <memory>
#include <iostream>
using namespace std;
using namespace boost;
class b{};
class c : public b{};
class d : public b{};
Instead of using a (smart) pointer to the base class b, you use a variant type:
using variant_t = variant<c, d>;
and variant variables:
variant_t v{c{}};
Now, if you want to handle c and d methods differently, you can use:
struct unique_visitor : public boost::static_visitor<void> {
void operator()(c c_) const { cout << "c" << endl; };
void operator()(d d_) const { cout << "d" << endl; };
};
which you would call with
apply_visitor(unique_visitor{}, v);
Note that you can also use the same mechanism to uniformly handle all types, by using a visitor that accepts the base class:
struct common_visitor : public boost::static_visitor<void> {
void operator()(b b_) const { cout << "b" << endl; };
};
apply_visitor(common_visitor{}, v);
Note that if the number of classes increases faster than the number of methods, this approach will cause maintenance problems.
Full code:
#include "boost/variant.hpp"
#include <iostream>
using namespace std;
using namespace boost;
class b{};
class c : public b{};
class d : public b{};
using variant_t = variant<c, d>;
struct unique_visitor : public boost::static_visitor<void> {
void operator()(c c_) const { cout << "c" << endl; };
void operator()(d d_) const { cout << "d" << endl; };
};
struct common_visitor : public boost::static_visitor<void> {
void operator()(b b_) const { cout << "b" << endl; };
};
int main() {
variant_t v{c{}};
apply_visitor(unique_visitor{}, v);
apply_visitor(common_visitor{}, v);
}
You can declare interfaces with pure methods for each device class. When you define a specific device implementation, you inherit only from the interfaces that make sense for it.
Using the interfaces that you define, you can then iterate and call methods which are specific to each device class.
In the following example I have declared a HardwareInterface which will be inherited by all devices, and an AlertInterface which will be inherited only by hardware devices that can physically alert a user. Other similar interfaces can be defined, such as SensorInterface, LEDInterface, etc.
#include <iostream>
#include <memory>
#include <vector>
class HardwareInteface {
public:
virtual void on() = 0;
virtual void off() = 0;
virtual char read() = 0;
virtual void write(char byte) = 0;
};
class AlertInterface {
public:
virtual void alert() = 0;
};
class Buzzer : public HardwareInteface, public AlertInterface {
public:
virtual void on();
virtual void off();
virtual char read();
virtual void write(char byte);
virtual void alert();
};
void Buzzer::on() {
std::cout << "Buzzer on!" << std::endl;
}
void Buzzer::off() {
/* TODO */
}
char Buzzer::read() {
return 0;
}
void Buzzer::write(char byte) {
/* TODO */
}
void Buzzer::alert() {
std::cout << "Buzz!" << std::endl;
}
class Vibrator : public HardwareInteface, public AlertInterface {
public:
virtual void on();
virtual void off();
virtual char read();
virtual void write(char byte);
virtual void alert();
};
void Vibrator::on() {
std::cout << "Vibrator on!" << std::endl;
}
void Vibrator::off() {
/* TODO */
}
char Vibrator::read() {
return 0;
}
void Vibrator::write(char byte) {
/* TODO */
}
void Vibrator::alert() {
std::cout << "Vibrate!" << std::endl;
}
int main(void) {
std::shared_ptr<Buzzer> buzzer = std::make_shared<Buzzer>();
std::shared_ptr<Vibrator> vibrator = std::make_shared<Vibrator>();
std::vector<std::shared_ptr<HardwareInteface>> hardware;
hardware.push_back(buzzer);
hardware.push_back(vibrator);
std::vector<std::shared_ptr<AlertInterface>> alerters;
alerters.push_back(buzzer);
alerters.push_back(vibrator);
for (auto device : hardware)
device->on();
for (auto alerter : alerters)
alerter->alert();
return 0;
}
Interfaces can be even more specific, as per individual sensor type: AccelerometerInterface, GyroscopeInterface, etc.
While what you ask is possible, it will either result in your code scattered with casts, or functions available on classes that make no sense. Both are undesirable.
If you need to know if it's a class C or D, then most likely either storing it as a B is wrong, or your interface B is wrong.
The whole point of polymorphism is that the things using B is that they don't need to know exactly what sort of B it is. To me, it sounds like you're extending classes rather than having them as members, ie "C is a B" doesn't make sense, but "C has a B does".
I would go back and reconsider what B,C,D and all future items do, and why they have these unique functions that you need to call; and look into if function overloading is what you really want to do. (Similar to Ami Tavory suggestion of visitor pattern)
you can use unique_ptr.get() to get the pointer in Unique Pointer,And the use the pointer as normall. like this:
for (auto &el : v) {
el->tell();
D* pd = dynamic_cast<D*>(el.get());
if (pd != nullptr)
{
pd->DFunc();
}
C* pc = dynamic_cast<C*>(el.get());
if (pc != nullptr)
{
pc->CFunc();
}
}
and the result is this:
CHILD C
Can be called only from C
CHILD D
Can be called only from D
You should use your 1st approach if you can to hide as much type-specific implementation details as possible.
Then, if you need public interfaces you should use virtual funtions (your 2nd approach), and avoid dynamic_cast (your 3rd approach). Many theads can tell you why (e.g. Polymorphism vs DownCasting). and you already mentioned one good reason, which is you shouldn't really check for the object type ...
If you have a problem with virtual functions because your drived classes have too many unique public interfaces, then it's not IS-A relationship and it's time to review your design. For example, for shared functionality, consider composition, rather than inheritance ...
There's been a lot of comments (in OP and Ami Tavory's answer) about visitor pattern.
I think it is and acceptable answer here (considering the OP question), even if visitor pattern has disadvantages, it also has advantages (see this topic: What are the actual advantages of the visitor pattern? What are the alternatives?). Basically, if you'll need to add a new child class later, the pattern implementation will force you to consider all cases where specific action for this new class has to be taken (compiler will force you to implement the new specific visit method for all your existing visitor child classes).
An easy implementation (without boost):
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class C;
class D;
class Visitor
{
public:
virtual ~Visitor() {}
virtual void visitC( C& c ) = 0;
virtual void visitD( D& d ) = 0;
};
class B{
private: int a; int b;
public: B(const int _a, const int _b) : a(_a), b(_b){}
virtual void tell(){ std::cout << "BASE" << std::endl; }
virtual void Accept( Visitor& v ) = 0; // force child class to handle the visitor
};
class C : public B{
std::string s;
public: C(int _a, int _b, std::string _s) : B(_a, _b), s(_s){}
void tell() override { std::cout << "CHILD C" << std::endl; }
void CFunc() {std::cout << "Can be called only from C" << std::endl;}
virtual void Accept( Visitor& v ) { v.visitC( *this ); }
};
class D : public B{
double d;
public: D(int _a, int _b, double _d) : B(_a, _b), d(_d){}
void tell() override { std::cout << "CHILD D" << std::endl; }
void DFunc() {std::cout << "Can be called only from D" << std::endl;}
virtual void Accept( Visitor& v ) { v.visitD( *this ); }
};
int main() {
std::vector<std::unique_ptr<B>> v;
v.push_back(std::make_unique<C>(1,2, "boom"));
v.push_back(std::make_unique<D>(1,2, 44.3));
// declare a new visitor every time you need a child-specific operation to be done
class callFuncVisitor : public Visitor
{
public:
callFuncVisitor() {}
virtual void visitC( C& c )
{
c.CFunc();
}
virtual void visitD( D& d )
{
d.DFunc();
}
};
callFuncVisitor visitor;
for(auto &el: v){
el->Accept(visitor);
}
return 0;
}
Live demo: https://ideone.com/JshiO6
Dynamic casting is the tool of absolute last resort. It is usually used when you are trying to overcome a poorly designed library that cannot be modified safely.
The only reason to need this sort of support is when you require parent and child instances to coexist in a collection. Right? The logic of polymorphism says all specialization methods that cannot logically exist in the parent should be referenced from within methods that do logically exist in the parent.
In other words, it is perfectly fine to have child class methods that don't exist in the parent to support the implementation of a virtual method.
A task queue implementation is the quintessential example (see below)
The special methods support the primary run() method. This allows a stack of tasks to be pushed into a queue and executed, no casts, no visitors, nice clean code.
// INCOMPLETE CODE
class Task
{
public:
virtual void run()= 0;
};
class PrintTask : public Task
{
private:
void printstuff()
{
// printing magic
}
public:
void run()
{
printstuff();
}
};
class EmailTask : public Task
{
private:
void SendMail()
{
// send mail magic
}
public:
void run()
{
SendMail();
}
};
class SaveTask : public Task
private:
void SaveStuff()
{
// save stuff magic
}
public:
void run()
{
SaveStuff();
}
};
Here's a "less bad" way of doing it, while keeping it simple.
Key points:
We avoid losing type information during the push_back()
New derived classes can be added easily.
Memory gets deallocated as you'd expect.
It's easy to read and maintain, arguably.
struct BPtr
{
B* bPtr;
std::unique_ptr<C> cPtr;
BPtr(std::unique_ptr<C>& p) : cPtr(p), bPtr(cPtr.get())
{ }
std::unique_ptr<D> dPtr;
BPtr(std::unique_ptr<D>& p) : dPtr(p), bPtr(dPtr.get())
{ }
};
int main()
{
std::vector<BPtr> v;
v.push_back(BPtr(std::make_unique<C>(1,2, "boom")));
v.push_back(BPtr(std::make_unique<D>(1,2, 44.3)));
for(auto &el: v){
el.bPtr->tell();
if(el.cPtr) {
el.cPtr->CFunc();
}
if(el.dPtr) {
el.dPtr->DFunc();
}
}
return 0;
}
first off: I have read and I know now that a virtual template member function is not (yet?) possible in C++. A workaround would be to make the class a template and then use the template-argument also in the member-function.
But in the context of OOP, I find that the below example would not be very "natural" if the class was actually a template. Please note that the code is actually not working, but the gcc-4.3.4 reports: error: templates may not be ‘virtual’
#include <iostream>
#include <vector>
class Animal {
public:
template< class AMOUNT >
virtual void eat( AMOUNT amount ) const {
std::cout << "I eat like a generic Animal." << std::endl;
}
virtual ~Animal() {
}
};
class Wolf : public Animal {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a wolf!" << std::endl;
}
virtual ~Wolf() {
}
};
class Fish : public Animal {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a fish!" << std::endl;
}
virtual ~Fish() {
}
};
class GoldFish : public Fish {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a goldfish!" << std::endl;
}
virtual ~GoldFish() {
}
};
class OtherAnimal : public Animal {
virtual ~OtherAnimal() {
}
};
int main() {
std::vector<Animal*> animals;
animals.push_back(new Animal());
animals.push_back(new Wolf());
animals.push_back(new Fish());
animals.push_back(new GoldFish());
animals.push_back(new OtherAnimal());
for (std::vector<Animal*>::const_iterator it = animals.begin(); it != animals.end(); ++it) {
(*it)->eat();
delete *it;
}
return 0;
}
So creating a "Fish< Amount > foo" is kind of strange. However, it seems desirable to me to provide an arbitrary amount of food to eat for each animal.
Thus, I am searching a solution about how to achieve something like
Fish bar;
bar.eat( SomeAmount food );
This becomes particularly useful when looking at the for-loop. One might like to feed a specific amount (FoodAmount) to all of the different animals (via eat() and bind1st() e.g.), it could not be done that easily, although I wound find this very inuitive (and thus to some extent "natural). While some might want to argue now that this is due to the "uniform"-character of a vector, I think/wish that it should be possible to achieve this and I really would like to know how, as this is puzzling me for quite some time now...
[EDIT]
To perhaps clarify the motivation behind my question, I want to program an Exporter-class and let different, more specialized classes derive from it. While the top-level Exporter-class is generally only for cosmetic/structural purpose, a GraphExporter-class is derived, that should again serve as a base-class for even more specialzed export. However, similar to the Animal-example, I would like to be able to define GraphExporter* even on specialized/derived classes (e.g. on SpecialGraphExplorer) but when calling "write( out_file )", it should call the appropriate member function for SpecialGraphExporter instead of GraphExporter::write( out_file).
Maybe this makes my situation and intentions clearer.
Best,
Shadow
After some thinking I recognized this as the classic multi-method requirement, i.e. a method that dispatches based on the runtime type of more than one parameter. Usual virtual functions are single dispatch in comparison (and they dispatch on the type of this only).
Refer to the following:
Andrei Alexandrescu has written (the seminal bits for C++?) on implementing multi-methods using generics in 'Modern C++ design'
Chapter 11: "Multimethods" - it implements basic multi-methods, making them logarithmic (using ordered typelists) and then going all the way to constant-time multi-methods. Quite powerful stuff !
A codeproject article that seems to have just such an implementation:
no use of type casts of any kind (dynamic, static, reinterpret, const or C-style)
no use of RTTI;
no use of preprocessor;
strong type safety;
separate compilation;
constant time of multimethod execution;
no dynamic memory allocation (via new or malloc) during multimethod call;
no use of nonstandard libraries;
only standard C++ features is used.
C++ Open Method Compiler, Peter Pirkelbauer, Yuriy Solodkyy, and Bjarne Stroustrup
The Loki Library has A MultipleDispatcher
Wikipedia has quite a nice simple write-up with examples on Multiple Dispatch in C++.
Here is the 'simple' approach from the wikipedia article for reference (the less simple approach scales better for larger number of derived types):
// Example using run time type comparison via dynamic_cast
struct Thing {
virtual void collideWith(Thing& other) = 0;
}
struct Asteroid : Thing {
void collideWith(Thing& other) {
// dynamic_cast to a pointer type returns NULL if the cast fails
// (dynamic_cast to a reference type would throw an exception on failure)
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Asteroid-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Asteroid-Spaceship collision
} else {
// default collision handling here
}
}
}
struct Spaceship : Thing {
void collideWith(Thing& other) {
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Spaceship-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Spaceship-Spaceship collision
} else {
// default collision handling here
}
}
}
Obviously, virtual member function templates are not allowed and could not be realized even theoretically. To build a base class' virtual table, there needs to be a finite number of virtual function-pointer entries. A function template would admit an indefinite amount of "overloads" (i.e. instantiations).
Theoretically-speaking, a language (like C++) could allow virtual member function templates if it had some mechanism to specify the actual (finite) list of instantiations. C++ does have that mechanism (i.e. explicit template instantiations), so I guess it could be possible to do this in a newer C++ standard (although I have no idea what trouble it would entail for compiler vendors to implement this feature). But, that's just a theoretical discussion, in practice, this is simply not allowed. The fact remains, you have to make the number of virtual functions finite (no templates allowed).
Of course, that doesn't mean that class template cannot have virtual functions, nor does it mean that virtual functions cannot call function templates. So, there are many solutions in that vein (like the Visitor pattern or other schemes).
One solution that, I think, serves your purpose (although it is hard to comprehend) elegantly is the following (which is basically a visitor pattern):
#include <iostream>
#include <vector>
struct Eater {
virtual void operator()(int amount) const = 0;
virtual void operator()(double amount) const = 0;
};
template <typename EaterType>
struct Eater_impl : Eater {
EaterType& data;
Eater_impl(EaterType& aData) : data(aData) { };
virtual void operator()(int amount) const { data.eat_impl(amount); };
virtual void operator()(double amount) const { data.eat_impl(amount); };
};
class Animal {
protected:
Animal(Eater& aEat) : eat(aEat) { };
public:
Eater& eat;
virtual ~Animal() { delete &eat; };
};
class Wolf : public Animal {
private:
template< class AMOUNT >
void eat_impl( AMOUNT amount) const {
std::cout << "I eat like a wolf!" << std::endl;
}
public:
friend struct Eater_impl<Wolf>;
Wolf() : Animal(*(new Eater_impl<Wolf>(*this))) { };
virtual ~Wolf() { };
};
class Fish : public Animal {
private:
template< class AMOUNT >
void eat_impl( AMOUNT amount) const {
std::cout << "I eat like a fish!" << std::endl;
}
public:
friend struct Eater_impl<Fish>;
Fish() : Animal(*(new Eater_impl<Fish>(*this))) { };
virtual ~Fish() { };
};
int main() {
std::vector<Animal*> animals;
animals.push_back(new Wolf());
animals.push_back(new Fish());
for (std::vector<Animal*>::const_iterator it = animals.begin(); it != animals.end(); ++it) {
(*it)->eat(int(0));
(*it)->eat(double(0.0));
delete *it;
};
return 0;
};
The above is a neat solution because it allows you to define a finite number of overloads that you want in one place only (in the Eater_impl class template) and all you need in the derived class is a function template (and possibly additional overloads, for special cases). There is, of course, a bit of overhead, but I guess that a bit more thought could be put into it to reduce the overhead (additional reference storage and dynamic allocation of Eater_impl). I guess, the curiously recurring template pattern could probably be employed somehow to this end.
I think the visitor pattern can be a solution.
UPDATE
I finished my example:
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
class Animal;
class Wolf;
class Fish;
class Visitor
{
public:
virtual void visit(const Animal& p_animal) const = 0;
virtual void visit(const Wolf& p_animal) const = 0;
virtual void visit(const Fish& p_animal) const = 0;
};
template<class AMOUNT>
class AmountVisitor : public Visitor
{
public:
AmountVisitor(AMOUNT p_amount) : m_amount(p_amount) {}
virtual void visit(const Animal& p_animal) const
{
std::cout << "I eat like a generic Animal." << std::endl;
}
virtual void visit(const Wolf& p_animal) const
{
std::cout << "I eat like a wolf!" << std::endl;
}
virtual void visit(const Fish& p_animal) const
{
std::cout << "I eat like a fish!" << std::endl;
}
AMOUNT m_amount;
};
class Animal {
public:
virtual void Accept(const Visitor& p_visitor) const
{
p_visitor.visit(*this);
}
virtual ~Animal() {
}
};
class Wolf : public Animal {
public:
virtual void Accept(const Visitor& p_visitor) const
{
p_visitor.visit(*this);
}
};
class Fish : public Animal {
public:
virtual void Accept(const Visitor& p_visitor) const
{
p_visitor.visit(*this);
}
};
int main()
{
typedef boost::shared_ptr<Animal> TAnimal;
std::vector<TAnimal> animals;
animals.push_back(TAnimal(new Animal()));
animals.push_back(TAnimal(new Wolf()));
animals.push_back(TAnimal(new Fish()));
AmountVisitor<int> amount(10);
for (std::vector<TAnimal>::const_iterator it = animals.begin(); it != animals.end(); ++it) {
(*it)->Accept(amount);
}
return 0;
}
this prints:
I eat like a generic Animal.
I eat like a wolf!
I eat like a fish!
Per Mikael's post, I have made another offshoot, using the CRTP and following Eigen's style of using derived() for an explicit subclass reference:
// Adaptation of Visitor Pattern / CRTP from:
// http://stackoverflow.com/a/5872633/170413
#include <iostream>
using std::cout;
using std::endl;
class Base {
public:
virtual void tpl(int x) = 0;
virtual void tpl(double x) = 0;
};
// Generics for display
template<typename T>
struct trait {
static inline const char* name() { return "T"; }
};
template<>
struct trait<int> {
static inline const char* name() { return "int"; }
};
template<>
struct trait<double> {
static inline const char* name() { return "double"; }
};
// Use CRTP for dispatch
// Also specify base type to allow for multiple generations
template<typename BaseType, typename DerivedType>
class BaseImpl : public BaseType {
public:
void tpl(int x) override {
derived()->tpl_impl(x);
}
void tpl(double x) override {
derived()->tpl_impl(x);
}
private:
// Eigen-style
inline DerivedType* derived() {
return static_cast<DerivedType*>(this);
}
inline const DerivedType* derived() const {
return static_cast<const DerivedType*>(this);
}
};
// Have Child extend indirectly from Base
class Child : public BaseImpl<Base, Child> {
protected:
friend class BaseImpl<Base, Child>;
template<typename T>
void tpl_impl(T x) {
cout << "Child::tpl_impl<" << trait<T>::name() << ">(" << x << ")" << endl;
}
};
// Have SubChild extend indirectly from Child
class SubChild : public BaseImpl<Child, SubChild> {
protected:
friend class BaseImpl<Child, SubChild>;
template<typename T>
void tpl_impl(T x) {
cout << "SubChild::tpl_impl<" << trait<T>::name() << ">(" << x << ")" << endl;
}
};
template<typename BaseType>
void example(BaseType *p) {
p->tpl(2);
p->tpl(3.0);
}
int main() {
Child c;
SubChild sc;
// Polymorphism works for Base as base type
example<Base>(&c);
example<Base>(&sc);
// Polymorphism works for Child as base type
example<Child>(&sc);
return 0;
}
Output:
Child::tpl_impl<int>(2)
Child::tpl_impl<double>(3)
SubChild::tpl_impl<int>(2)
SubChild::tpl_impl<double>(3)
SubChild::tpl_impl<int>(2)
SubChild::tpl_impl<double>(3)
This snippet may be found in source here: repro:c808ef0:cpp_quick/virtual_template.cc
Virtual template function is not allowed. However you can use one OR the other here.
You could make an interface using virtual methods and implement your various animals in terms of having an eating interface. (i.e. PIMPL)
Less human intuitive would be having a non-member non-friend template function as a free function which could take templated const reference to any animal and make them eat accordingly.
For the record you don't need templates here. Pure virtual abstract method on the base class is enough to force and interface where all animals must eat and define how they do so with an override, providing a regular virtual would be enough to say all animals can eat but if they don't have a specific way then they can use this default way.
You can create a template class with virtual function, and implement the function in the derived class without using template in the follwing way:
a.h:
template <class T>
class A
{
public:
A() { qDebug() << "a"; }
virtual A* Func(T _template) { return new A;}
};
b.h:
class B : public A<int>
{
public:
B();
virtual A* Func(int _template) { return new B;}
};
and the function CTOR and call
A<int>* a1=new B;
int x=1;
a1->Func(x);
unfortunately i havn't found a way to create a virtual function with template parameters without declaring the class as a template and it template type on the dervied class
I have copied your code and modified it, so now it should work exactly as you want:
#include <iostream>
#include <vector>
//defined new enum type
enum AnimalEnum
{
animal,
wolf,
fish,
goldfish,
other
};
//forward declarations
class Wolf;
class Fish;
class GoldFish;
class OtherAnimal;
class Animal {
private:
AnimalEnum who_really_am_I;
void* animal_ptr;
public:
//declared new constructors overloads for each type of animal
Animal(const Animal&);
Animal(const Wolf&);
Animal(const Fish&);
Animal(const GoldFish&);
Animal(const OtherAnimal&);
template< class AMOUNT >
/*removed the virtual keyword*/ void eat( AMOUNT amount ) const {
switch (this->who_really_am_I)
{
case AnimalEnum::other: //You defined OtherAnimal so that it doesn't override the eat action, so it will uses it's Animal's eat
case AnimalEnum::animal: std::cout << "I eat like a generic Animal." << std::endl; break;
case AnimalEnum::wolf: ((Wolf*)this->animal_ptr)->eat(amount); break;
case AnimalEnum::fish: ((Fish*)this->animal_ptr)->eat(amount); break;
case AnimalEnum::goldfish: ((GoldFish*)this->animal_ptr)->eat(amount) break;
}
}
void DeleteMemory() { delete this->animal_ptr; }
virtual ~Animal() {
//there you can choose if whether or not to delete "animal_ptr" here if you want or not
}
};
class Wolf : public Animal {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a wolf!" << std::endl;
}
virtual ~Wolf() {
}
};
class Fish : public Animal {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a fish!" << std::endl;
}
virtual ~Fish() {
}
};
class GoldFish : public Fish {
public:
template< class AMOUNT >
void eat( AMOUNT amount) const {
std::cout << "I eat like a goldfish!" << std::endl;
}
virtual ~GoldFish() {
}
};
class OtherAnimal : public Animal {
//OtherAnimal constructors must be defined here as Animal's constructors
OtherAnimal(const Animal& a) : Animal(a) {}
OtherAnimal(const Wolf& w) : Animal(w) {}
OtherAnimal(const Fish& f) : Animal(f) {}
OtherAnimal(const GoldFish& g) : Animal(g) {}
OtherAnimal(const OtherAnimal& o) : Animal(o) {}
virtual ~OtherAnimal() {
}
};
//OtherAnimal will be useful only if it has it's own actions and members, because if not, typedef Animal OtherAnimal or using OtherAnimal = Animal can be used, and it can be removed from above declarations and below definitions
//Here are the definitions of Animal constructors that were declared above/before:
Animal::Animal(const Animal& a) : who_really_am_I(AnimalEnum::animal), animal_ptr(nullptr) {}
Animal::Animal(const Wolf& w) : who_really_am_I(AnimalEnum::wolf), animal_ptr(new Wolf(w)) {}
Animal::Animal(const Fish& f) : who_really_am_I(AnimalEnum::fish), animal_ptr(new Fish(f)) {}
Animal::Animal(const GoldFish& g) : who_really_am_I(AnimalEnum::goldfish), animal_ptr(new GoldFish(g)) {}
Animal::Animal(const OtherAnimal& o) :
who_really_am_I(AnimalEnum::other), animal_ptr(new OtherAnimal(o)) {}
int main() {
std::vector<Animal> animals;
animals.push_back(Animal());
animals.push_back(Wolf()); //Wolf is converted to Animal via constructor
animals.push_back(Fish()); //Fish is converted to Animal via constructor
animals.push_back(GoldFish()); //GoldFish is converted to Animal via constructor
animals.push_back(OtherAnimal()); //OtherAnimal is converted to Animal via constructor
for (std::vector<Animal>::const_iterator it = animals.begin(); it != animals.end(); ++it) {
it->eat(); //this is Animal's eat that invokes other animals eat
//delete *it; Now it should be:
it->DeleteMemory();
}
animals.clear(); //All animals have been killed, and we don't want full vector of dead animals.
return 0;
}
In you scenario, you are trying to mix compile time polymorphism with runtime polymorphism, but it cannot be done in this "direction".
Essential, your AMOUNT template argument represents an expected interface for the type to implement based on the union of all the operations each implementation of eat uses. If you where to create an abstract type that declared each of those operations making them virtual where needed, then you could call eat with different types (that derived from your AMOUNT interface). And it would behave as expected.
I don't work with templates, but I think:
(1) You cannot use templates inside a class, templates are more like global types or global variables.
(2) In O.O.P., the same problem you present, and that you are trying to solve by using templates, can be solved by using inheritance.
Classes work similar to templates, you can extended by adding new things, or replace things of classes with pointers, pointers to objects (A.K.A. "references") and overriding virtual functions.
#include <iostream>
struct Animal {
virtual void eat(int amount ) {
std::cout << "I eat like a generic Animal." << std::endl;
}
virtual ~Animal() { }
};
#if 0
// example 1
struct Wolf : Animal {
virtual void eat(int amount) {
std::cout << "I eat like a wolf!" << std::endl;
}
};
struct Fish : Animal {
virtual void eat(int amount) {
std::cout << "I eat like a fish!" << std::endl;
}
};
#else
// example 2
struct AnimalFood {
virtual int readAmount() { return 5; }
virtual void showName() {
std::cout << "I'm generic animal food" << std::endl;
}
};
struct PredatorFood : AnimalFood {
virtual int readAmount() { return 500; }
virtual void showName() {
std::cout << "I'm food for a predator" << std::endl;
}
};
struct Fish : Animal {
virtual void eat(AnimalFood* aFood) {
if (aFood->readAmount() < 50) {
std::cout << "OK food, vitamines: " << aFood->readAmount() << std::endl;
} else {
std::cout << "too much food, vitamines: " << aFood->readAmount() << std::endl;
}
}
};
struct Shark : Fish {
virtual void eat(AnimalFood* aFood) {
if (aFood->readAmount() < 250) {
std::cout << "too litle food for a shark, Im very hungry, vitamines: " << aFood->readAmount() << std::endl;
} else {
std::cout << "OK, vitamines: " << aFood->readAmount() << std::endl;
}
}
};
struct Wolf : Fish {
virtual void eat(AnimalFood* aFood) {
if (aFood->readAmount() < 150) {
std::cout << "too litle food for a wolf, Im very hungry, vitamines: " << aFood->readAmount() << std::endl;
} else {
std::cout << "OK, vitamines: " << aFood->readAmount() << std::endl;
}
}
};
#endif
int main() {
// find animals
Wolf* loneWolf = new Wolf();
Fish* goldenFish = new Fish();
Shark* sharky = new Shark();
// prepare food
AnimalFood* genericFood = new AnimalFood();
PredatorFood* bigAnimalFood = new PredatorFood();
// give food to animals
loneWolf->eat(genericFood);
loneWolf->eat(bigAnimalFood);
goldenFish->eat(genericFood);
goldenFish->eat(bigAnimalFood);
sharky->eat(genericFood);
sharky->eat(bigAnimalFood);
delete bigAnimalFood;
delete genericFood;
delete sharky;
delete goldenFish;
delete loneWolf;
}
Cheers.
This is part 2 to a problem I previously asked: Is it possible to have polymorphic member overloading in C++?
Using the Wiki example I created this example.
http://en.wikipedia.org/wiki/Double_dispatch
My problem is that the compiled code never looks up the vtable, and always uses the base instead of the inherited class. Here is my code:
#include <iostream>
class xEntity;
class xVehicle;
class xMapObject
{
public:
virtual void Bump(xMapObject&) { std::cout << "MapObject Bump MapObject\n"; };
virtual void Bump(xEntity&) { std::cout << "MapObject Bump Entity\n"; };
virtual void Bump(xVehicle&) { std::cout << "MapObject Bump Vehicle\n"; };
};
class xEntity : public xMapObject
{
public:
virtual void Bump(xMapObject&) { std::cout << "Entity Bump MapObject\n"; };
virtual void Bump(xEntity&) { std::cout << "Entity Bump Entity\n"; };
virtual void Bump(xVehicle&) { std::cout << "Entity Bump Vehicle\n"; };
};
class xVehicle : public xEntity
{
public:
virtual void Bump(xMapObject&) { std::cout << "Vehicle Bump MapObject\n"; };
virtual void Bump(xEntity&) { std::cout << "Vehicle Bump Entity\n"; };
virtual void Bump(xVehicle&) { std::cout << "Vehicle Bump Vehicle\n"; };
};
int main(int argv, char **argc)
{
xEntity Entity;
xVehicle Vechile;
xMapObject &EntityRef = Entity;
xMapObject &VehicleRef = Vechile;
VehicleRef.Bump(EntityRef);
return 0;
}
However, the output is always:
Vehicle Bump MapObject
Any help on this mystery is greatly appreciated.
You only did single dispatch, not double dispatch. The idea is that in xVehicle, taking an xMapObject&, you would call ref.bump(*this); which is double dispatch.
It is using the vtable; that's why it's calling xVechicle::Bump()! The vtable isn't used on arguments, that doesn't make sense (in C++, at least).
The typical solution is to have e.g. Bump(xMapObject& obj) call obj.Bump(*this);.
Is a bad design the xEntity::Bump(xVehicle&) because you are using as parameter in a base class a derived class.
and at least that your contract change, you don't need redefine base Bump methods.
the problem is that you are creating the xMapRef vars, that convert your derived class to a base class.
if you want that appropriated method is called, just call with the derived class object
Due to the well-known issues with calling virtual methods from inside constructors and destructors, I commonly end up with classes that need a final-setup method to be called just after their constructor, and a pre-teardown method to be called just before their destructor, like this:
MyObject * obj = new MyObject;
obj->Initialize(); // virtual method call, required after ctor for (obj) to run properly
[...]
obj->AboutToDelete(); // virtual method call, required before dtor for (obj) to clean up properly
delete obj;
This works, but it carries with it the risk that the caller will forget to call either or both of those methods at the appropriate times.
So the question is: Is there any way in C++ to get those methods to be called automatically, so the caller doesn't have to remember to do call them? (I'm guessing there isn't, but I thought I'd ask anyway just in case there is some clever way to do it)
While there is no automated way, you could force the users hand by denying users access to the destructor on that type and declaring a special delete method. In this method you could do the virtual calls you'd like. Creation can take a similar approach which a static factory method.
class MyObject {
...
public:
static MyObject* Create() {
MyObject* pObject = new MyObject();
pObject->Initialize();
return pObject;
}
Delete() {
this->AboutToDelete();
delete this;
}
private:
MyObject() { ... }
virtual ~MyObject() { ... }
};
Now it is not possible to call "delete obj;" unless the call site has access to MyObject private members.
The best I can think of is for you to implement your own smart pointer with a static Create method that news up an instance and calls Initialize, and in its destructor calls AboutToDelete and then delete.
I used a very carefully designed Create() factory method (static member of each class) to call a constructor and initializer pair in the same order as C# initializes types. It returned a shared_ptr to an instance of the type, guaranteeing a heap allocation. It proved reliable and consistent over time.
The trick: I generated my C++ class declarations from XML...
Except for JavedPar's idea for the pre-destruction method, there is no pre-made solution to easily do two-phase construction/destruction in C++. The most obvious way to do this is to follow the Most Common Answer To Problems In C++: "Add another layer of indirection."
You can wrap objects of this class hierarchy within another object. That object's constructors/destructor could then call these methods. Look into Couplien's letter-envelop idiom, for example, or use the smart pointer approach already suggested.
http://www.research.att.com/~bs/wrapper.pdf This paper from Stroustrup will solve your problem.
I tested this under VS 2008 and on UBUNTU against g++ compiler. It worked fine.
#include <iostream>
using namespace std;
template<class T>
class Wrap
{
typedef int (T::*Method)();
T* p;
Method _m;
public:
Wrap(T*pp, Method m): p(pp), _m(m) { (p->*_m)(); }
~Wrap() { delete p; }
};
class X
{
public:
typedef int (*Method)();
virtual int suffix()
{
cout << "X::suffix\n";
return 1;
}
virtual void prefix()
{
cout << "X::prefix\n";
}
X() { cout << "X created\n"; }
virtual ~X() { prefix(); cout << "X destroyed\n"; }
};
class Y : public X
{
public:
Y() : X() { cout << "Y created\n"; }
~Y() { prefix(); cout << "Y destroyed\n"; }
void prefix()
{
cout << "Y::prefix\n";
}
int suffix()
{
cout << "Y::suffix\n";
return 1;
}
};
int main()
{
Wrap<X> xx(new X, &X::suffix);
Wrap<X>yy(new Y, &X::suffix);
}
I was stuck with the same problem, and after a bit of research, I believe there is not any standard solution.
The suggestions that I liked most are the ones provided in the Aleksandrescu et al. book "C++ coding standards" in the item 49.
Quoting them (fair use), you have several options:
Just document it that you need a second method, as you did.
Have another internal state (a boolean) that flags if post-construction has taken place
Use virtual class semantics, in the sense that the constructor of the most-derived class decides which base class to use
Use a factory function.
See his book for details.
You can use static function template in the class. With private ctor/dtor.
Run on vs2015 community
class A {
protected:
A() {}
virtual ~A() {}
virtual void onNew() = 0;
virtual void onDelete() = 0;
public:
void destroy() {
onDelete();
delete this;
}
template <class T> static T* create() {
static_assert(std::is_base_of<A, T>::value, "T must be a descendant of A");
T* t = new T();
t->onNew();
return t;
}
};
class B: public A {
friend A;
protected:
B() {}
virtual ~B() {}
virtual void onNew() override {
}
virtual void onDelete() override {
}
};
int main() {
B* b;
b = A::create<B>();
b->destroy();
}
The main problem with adding post-constructors to C++ is that nobody has yet established how to deal with post-post-constructors, post-post-post-constructors, etc.
The underlying theory is that objects have invariants. This invariant is established by the constructor. Once it has been established, methods of that class can be called. With the introduction of designs that would require post-constructors, you are introducing situations in which class invariants do not become established once the constructor has run. Therefore, it would be equally unsafe to allow calls to virtual functions from post-constructors, and you immediately lose the one apparent benefit they seemed to have.
As your example shows (probably without you realizing), they're not needed:
MyObject * obj = new MyObject;
obj->Initialize(); // virtual method call, required after ctor for (obj) to run properly
obj->AboutToDelete(); // virtual method call, required before dtor for (obj) to clean up properly
delete obj;
Let's show why these methods are not needed. These two calls can invoke virtual functions from MyObject or one of its bases. However, MyObject::MyObject() can safely call those functions too. There is nothing that happens after MyObject::MyObject() returns which would make obj->Initialize() safe. So either obj->Initialize() is wrong or its call can be moved to MyObject::MyObject(). The same logic applies in reverse to obj->AboutToDelete(). The most derived destructor will run first and it can still call all virtual functions, including AboutToDelete().
I had the same problem for construction. This is my solution using C++14.
The idea is to declare an instance of the class Call in the same (or quite close) scope than the declaration of the final object, letting the destructor call the post-creation script.
# include <iostream>
# include <cassert>
# include <memory>
# include <typeinfo>
class A;
// This non-template class stores an access to the instance
// on which a procedure must be called after construction
// The functions are defined after A in order to avoid a loop
class Call
{
protected:
A* a;
public:
Call();
virtual ~Call();
virtual void set(A& a_) = 0;
};
// In this class, the Source must be the final type created
template <typename Source>
class Call_ : public Call
{
static_assert(std::is_final<Source>::value, "");
public:
Call_() : Call() {}
virtual ~Call_() { assert(typeid(*this->a) == typeid(Source)); }
virtual void set(A& a_) { this->a = &a_; }
};
class A
{
protected:
A(Call& call) { std::cout << "Build A" << std::endl; call.set(*this); } // <----
public:
A(A const&) { std::cout << "Copy A" << std::endl; }
virtual ~A() { std::cout << "Delete A" << std::endl; }
virtual void actions_after_construction() = 0; // post-creation procedure
};
Call::Call() : a(nullptr)
{}
Call::~Call()
{
assert(this->a);
this->a->actions_after_construction();
}
class B : public A
{
protected:
B(Call& call) : A(call) { std::cout << "Build B" << std::endl; }
public:
B(B const& b) : A(b) { std::cout << "Copy B" << std::endl; }
virtual ~B() { std::cout << "Delete B" << std::endl; }
virtual void actions_after_construction() { std::cout << "actions by B" << std::endl; }
};
class C final : public B
{
private:
C(Call& call) : B(call) { std::cout << "Build C" << std::endl; }
public:
C(std::shared_ptr<Call> p_call = std::shared_ptr<Call>(new Call_<C>)) : C(*p_call) {}
C(C const& c) : B(c) { std::cout << "Copy C" << std::endl; }
virtual ~C() { std::cout << "Delete C" << std::endl; }
virtual void actions_after_construction() { std::cout << "actions by C" << std::endl; }
};
class D final : public B
{
private:
D(Call& call) : B(call) { std::cout << "Build D" << std::endl; }
public:
D(std::shared_ptr<Call> p_call = std::shared_ptr<Call>(new Call_<D>)) : D(*p_call) {}
D(D const& d) : B(d) { std::cout << "Copy D" << std::endl; }
virtual ~D() { std::cout << "Delete D" << std::endl; }
virtual void actions_after_construction() { std::cout << "actions by D" << std::endl; }
};
int main()
{
{ C c; }
{ D d; }
return 0;
}
Haven't seen the answer yet, but base classes are only one way to add code in a class hierarchy. You can also create classes designed to be added to the other side of the hierarchy:
template<typename Base>
class Derived : public Base {
// You'd need C++0x to solve the forwarding problem correctly.
Derived() : Base() {
Initialize();
}
template<typename T>
Derived(T const& t): Base(t) {
Initialize();
}
//etc
private:
Initialize();
};