Not sure how to explain it well, so I will just provide a sample of code that shows my problem:
class Base {
public:
Base() = default;
~Base() = default;
virtual void stuff(std::shared_ptr<Base> b) = 0;
};
class DerivedA : public Base {
public:
DerivedA() = default;
~DerivedA() = default;
void stuff(std::shared_ptr<Base> b) {
std::cout << "stuff Base"
<< "\n";
}
};
class DerivedB : public Base {
public:
DerivedB() = default;
~DerivedB() = default;
void stuff(std::shared_ptr<Base> b) {
std::cout << "stuff Base"
<< "\n";
}
void stuff(std::shared_ptr<DerivedA> b) {
std::cout << "stuff Derived"
<< "\n";
}
};
int main(int argc, char *argv[]) {
std::shared_ptr<Base> b1(new DerivedA());
std::shared_ptr<Base> b2(new DerivedB());
b1->stuff(b2);
b2->stuff(b1);
return 0;
}
The output will be:
stuff Base
stuff Base
Now, I suppose it is not possible to call the derived method as it doesn't exist in the base class.
My question is: Is there a way to call stuff(std::shared_ptr<DerivedA> b) using the base class ?
[EDIT]
I already thought about the visitor pattern (should have said it and be more specific).
My classes represent Entities and I have to check collisions between them. However a collision between A & B will have a different effect than between B & C.
I agree that it will work, but it means that I will have to define tons of methods.
Is there a more elegant way to do it ?
Thanks in advance.
What you are looking for is commonly called multiple dispatch, or a multimethod. There is no direct language support for this in C++, but you can explicitly implement it yourself. Basically, you have one virtual function which dispatches to another virtual function with a concrete object:
struct DerivedA;
struct DerivedB;
struct Base {
virtual ~Base() = default;
virtual void stuff(shared_ptr<Base> ) = 0;
virtual void dispatch_stuff(Base& ) = 0;
virtual void dispatch_stuff(DerivedA& p) { return dispatch_stuff(static_cast<Base&>(p)); }
virtual void dispatch_stuff(DerivedB& p) { return dispatch_stuff(static_cast<Base&>(p)); }
struct DerivedA : Base {
void stuff(shared_ptr<Base> rhs) override {
rhs->dispatch_stuff(*this);
}
void dispatch_stuff(Base& ) { /* default */ }
void dispatch_stuff(DerivedA& ) { /* specific A-A stuff */ }
};
This way:
b1->stuff(b2); // calls b2->dispatch_stuff(DerivedA& )
b2->stuff(b1); // calls b1->dispatch_stuff(DerivedB& )
My question is: Is there a way to call
stuff(std::shared_ptr<DerivedA> b) using the base class ?
No, because the Base class interface doesn't implement the method you want to call. Even though the Base class pointer is referring to a DerivedB object, and through poilformism you can resolve the method with the respect to the type of the object pointed by the pointer (i.e. DerivedB), you can only call the method defined in the Base class. Therefore, you cannot call stuff(std::shared_ptr<DerivedA> b) using a Base pointer that points to a DerivedB object.
For example:
std::shared_ptr<Base> b1(new DerivedA());
std::shared_ptr<Base> b2(new DerivedB());
std::shared_ptr<DerivedA> a1(new DerivedA());
std::shared_ptr<DerivedB> bb1(new DerivedB());
b1->stuff(b2);
b2->stuff(b1);
b2->stuff(a1); // b2 is the only class that implement stuff(std::shared_ptr<DerivedA> b)
bb1->stuff(a1)
output:
stuff Base
stuff Base
stuff Base
stuff Derived
stuff Base
The problem you are trying to solve is called the double dispatch problem, which means you're trying to invoke a behaviour depending on the concrete type of two objects. Looking up this term on google or here may yield you some interesting results.
First thing, one way or another, you're going to have to write a lot of functions since if you have N different types there are NN possible pairings. (NN/2 if order doesn't matter, which is probably the case in your collision scenario).
The visitor pattern is one of the canonical solutions to the double dispatch problem.
There are others, depending on what matters to you. Off the top of my head, for example, if the number of subtypes is limited and known at compile time, you can for example have an index for each type and a 2D array of function pointers to call (not very elegant nor very object oriented but quite efficient in terms of performance).
If you fear that the number of functions is likely to cause code duplication you can always factor the code inside a function, or a class ( something like CollisionPairBehavior ).
Related
Static code analysis tools tend to ramble a lot about "downcasting a base class to a derived class" and I also found a couple of coding standard guides, which mention not to do this so I was wondering what is the best-practice way.
Here's my use case:
I have a Base (interface), DerivedA, DerivedB classes and then an array containing Base pointers.
Then I iterate through the array and based on a flag, I determine if the object is DerivedA or DerivedB, cast it down and do some random stuff to the object from the outside.
Basically something like this:
// arr is of type Base**
for (int i = 0; i < size; ++i)
{
// doMagic has an overload for both types
if (arr[i]->isDerivedA())
{
doMagic(reinterpret_cast<DerivedA*>(arr[i]));
}
else if (arr[i]->isDerivedB())
{
doMagic(reinterpret_cast<DerivedB*>(arr[i]));
}
}
Bout the reinterpret, I cannot use dynamic_cast due to embedded platform restrictions (the same for C++11), but the Base class being an interface guarantees that the object is either DerivedA or DerivedB.
I could make DerivedA and DerivedB only implement pure virtual calls, thus i wouldn't have to worry about downcasting anything, but the DerivedA and DerivedB classes are very much specialized and doMagic does completely different things with the instances...
So I was wondering how you guys approach this - having a single array of very different objects, but inherited from a single base, iterating through them and doing some specialized stuff from the outside.
You probably should try to use visitor pattern.
Here is a simple example:
#include <cstdio>
class A;
class B;
class Visitor {
public:
void visit(A &a) {
printf("Visited A\n");
}
void visit(B &) {
printf("Visited B\n");
}
};
class A {
public:
virtual ~A() { }
virtual void applyVisitor(Visitor &v) {
v.visit(*this);
}
};
class B : public A {
public:
~B() override { }
void applyVisitor(Visitor &v) override {
v.visit(*this);
}
};
int main() {
A a;
B b;
Visitor v;
a.applyVisitor(v);
b.applyVisitor(v);
return 0;
}
If you know that a pointer of a base class points to an object of a derived class, you may use static_cast. The compiler will insert appropriate code to adjust offsets, unlike reinterpret_cast or a C-Cast.
I've got a base class that has a virtual function. I want to call that class during the construction because I want the function called for each of the derived classes. I know I can't call a virtual function during construction, but I can't think of an elegant (i.e., avoid repeating code) solution.
What are some work arounds to calling a virtual function during construction?
The reason I want to avoid this is because I don't want to have to create constructors that just call the base class.
class A {
public:
A() {
read();
}
// This never needs to be called
virtual void read() = 0;
}
class B:A {
public:
B():A() { };
read() { /*Do something special for B here.*/ }
}
class C:A {
public:
C():A() { };
read() { /*Do something special for C here.*/ }
}
PS: The Python way of doing this is simply to raise NotImplementedError in A::read(). I'm returning to C++ and I'm more rusty than I thought.
The FAQ perspective.
This is a Frequently Asked Question.
See the C++ FAQ item titled “Okay, but is there a way to simulate that behavior as if dynamic binding worked on the this object within my base class's constructor?”.
It’s very often a good idea to check the FAQ (and generally, googling or altavista’ing) before asking.
The question as “Derived class specific base initialization”.
To be clear, while the literal question above is
“What are some work arounds to calling a virtual function during construction?”
it is evident that what’s meant is
“How can a base class B be designed so that each derived class can specify part of what goes on during B construction?”
A major example is where C style GUI functionality is wrapped by C++ classes. Then a general Widget constructor might need to instantiate an API-level widget which, depending on the most derived class, should be a button widget or a listbox widget or whatever. So the most derived class must somehow influence what goes on up in Widget’s constructor.
In other words, we’re talking about derived class specific base construction.
Marshall Cline called that “Dynamic Binding During Construction”, and it’s problematic in C++ because in C++ the dynamic type of an object during class T construction and destruction, is T. This helps with type safety, in that a virtual member function is not called on a derived class sub-object before that sub-object has been initialized, or its initialization has started. But a major cost is that DBDI (apparently) can’t be done in a way that is both simple and safe.
Where the derived class specific init can be performed.
In the question the derived class specific action is called read. Here I call it derived_action. There are 3 main possibilities for where the derived_action is invoked:
Invoked by instantiation code, called two-phase construction.
This essentially implies the possibility of having a mostly unusuable not fully initialized object at hand, a zombie object. However, with C++11 move semantics that has become more common and accepted (and anyway it can be mitigated to some extent by using factories). A main problem is that during the second phase of construction the ordinary C++ protection against virtual calls on uninitialized sub-objects, due to dynamic type changes during construction, is not present.
Invoked by Derived constructor.
For example, derived_action can be invoked as an argument expression for the Base constructor. A not totally uncommon technique is to use a class template to generate most derived classes that e.g. supply calls of derived_action.
Invoked by Base constructor.
This implies that knowledge of derived_action must be passed up to the constructor, dynamically or statically. A nice way is to use a defaulted constructor argument. This leads to the notion of a parallel class hierarchy, a hierarchy of derived class actions.
This list is in order of increasing sophistication and type safety, and also, to the best of my knowledge, reflects the historical use of the various techniques.
E.g. in Microsoft’s MFC and Borland’s ObjectWindows GUI early 1990’ libraries two-phase construction was common, and that kind of design is now, as of 2014, regarded as very ungood.
This is the factory method approach, putting the factory into the base class:
class A {
public:
virtual void read() = 0;
template<class X> static X* create() {X* r = new X;X->read();return X;}
virtual A* clone() const = 0;
};
class B : public A {
B():A() { };
friend class A;
public:
void read() { /*Do something special for B here.*/ }
B* clone() const {return new B(*this);}
};
class C : public A {
C():A() { };
friend class A;
public:
void read() { /*Do something special for C here.*/ }
C* clone() const {return new C(*this);}
};
Added a clone-method with covariant return type as a bonus.
Using CRTP:
class A {
public:
// This never needs to be called
virtual void read() = 0;
virtual A* clone() const = 0;
};
template<class D, class B> struct CRTP : B {
D* clone() {return new D(*this);}
static D* create() {return new D();}
};
class B : public CRTP<B, A> {
B() { };
public:
void read() { /*Do something special for B here.*/ }
};
class C : public CRTP<C, A> {
C() { };
public:
void read() { /*Do something special for C here.*/ }
};
One way to achieve this, would be simply to delegate it to another class (that is perhaps a friend) and can be sure to be called when fully constructed.
class A
{
friend class C;
private:
C& _c; // this is the actual class!
public:
A(C& c) : _c(c) { };
virtual ~A() { };
virtual void read() = 0;
};
class B : public A
{
public:
B(C& c) : A(c) { };
virtual ~B() { };
virtual void read() {
// actual implementation
};
};
class C
{
private:
std::unique_ptr<A> _a;
public:
C() : _a(new B(*this)) { // looks dangerous? not at this point...
_a->read(); // safe now
};
};
In this example, I just create a B, but how you do that can depend on what you want to achieve and use templates on C if necessary, e.g:
template<typename VIRTUAL>
class C
{
private:
using Ptr = std::unique_ptr<VIRTUAL>;
Ptr _ptr;
public:
C() : _ptr(new VIRTUAL(*this)) {
_ptr->read();
};
}; // eo class C
The workaround is to call the virtual function after construction. You can then couple the two operations (construction + virtual call) in factory function. Here is the basic idea:
class FactoryA
{
public:
A *MakeA() const
{
A *ptr = CreateA();
ptr->read();
return ptr;
}
virtual ~FactoryA() {}
private:
virtual A *CreateA() const = 0;
};
class FactoryB : public FactoryA
{
private:
virtual A *CreateA() const { return new B; }
};
// client code:
void f(FactoryA &factory)
{
A *ptr = factory.MakeA();
}
As mentioned by Benjamin Bannier, you can use CRTP (a template which defines the actual read() function.) One problem with that method is that templates have to always be written inline. That can at times be problematic, especially if you are to write really large functions.
Another way is to pass a function pointer to the constructor. Although, in a way, it is similar to calling the function in your constructor, it forces you to pass a pointer (although in C++ you could always pass nullptr.)
class A
{
public:
A(func_t f)
{
// if(!f) throw ...;
(*f)();
}
};
class B : A
{
public:
B() : A(read) {}
void read() { ... }
};
Obviously, you have the "can't call other virtual functions" problem within the read() function and any function it calls. Plus, variable members of B are NOT yet initialized. That is probably a much worst problem in this case...
For that reason, writing it this way is safer:
B() : A()
{
read();
}
However, in cases like that, that may be the time when you an some for of init() function. That init() function can be implemented in A() (if you make it accessible: i.e. use public A when deriving) and that function can call all the virtual functions as expected:
class A
{
public:
void init()
{
read();
}
};
class B : public A
{
public:
...
};
I know a lot of people say that an init() function is evil because people who create a B object now need to know to call it... but there isn't much else you can do. That being said, you could have a form of factory, and that factory can do the init() call as required.
class B : public A
{
public:
static B *create() { B *b(new B); b->init(); return b; }
private:
B() { ... } // prevent creation without calling create()
};
I would like to force a certain API for all classes derived from the base class. Normally, you do that using an abstract base class that has purely virtual functions. However, how do you handle functions that return the derived type? How do I go about forcing that type of function?
struct base
{
virtual base func() = 0;
};
struct deriv1 : base
{
deriv1 func();
};
struct deriv2 : base
{
deriv2 func();
};
This example will give an error like "invalid abstract return type for member function". I've seen some answers that suggest returning pointers, but I don't particularly want to dip into dynamic memory for that and keeping track of all the allocated pointers would be a special kind of hell. Any ideas?
When a virtual function returns a pointer or reference to a class, a class which inherits from the base class and overrides the function is allowed to change the return type to a pointer or reference to a class which is derived from the original return type.
You can't return base by value as it is abstract so you can't actually create one by itself.
http://en.wikipedia.org/wiki/Covariant_return_type
When using virtual functions and base classes, you usually have to use dynamic allocation to create your objects. I suggest you look into smart pointers to help manage the memory.
In your example, the func won't be "the same function", so the deriv1 and deriv2 variants won't have a different virtual function.
Unfortunately, there is no other alternative than to return a pointer - it doesn't have to be a pointer to dynamically allocated memory (you could for example return a pointer to this or a static deriv2 anObject; - but it needs to be a pointer to base. [Or a reference, but the same problem applies].
The main reason for this (aside from the fact that "functions can't be differentiated only on return type") is that if you have some generic code that looks something like this:
vector<base*> v;
... stuff a bunch of `dervi1` or `deriv2` objects into v.
for(i : v)
{
base b = i->func();
}
Now, either you have now cut off [sliced] your deriv1 or deriv2 into the size of a base, or you'd have copied an object that is larger than base into a base-size object - neither of which will be of any benefit whatsoever. [I'm assuming that in the REAL use-case for this, deriv1 and deriv2 are in fact different from base by more aspects than the name of the object - otherwise, it's quite pointless. And that deriv1 and deriv2 are inheriting from base, of course].
In other words, you can't copy an object of unknown type with =. And it's absolutely no point in having a virtual function if you have to know what type it returns.
Basically a way of saying "If you want to replace deriv1 with deriv2 in your code, you need to implement these functions"
From your quote here above, it looks like you want something like this:
#include <memory> //for unique_ptr
#include <iostream>
struct Base
{
virtual void doX() = 0;
virtual void doY() = 0;
virtual ~Base(){}
};
struct D1 : Base
{
virtual void doX()
{
std::cout << "D1::doX()" << std::endl;
}
virtual void doY()
{
std::cout << "D1::doY()" << std::endl;
}
};
struct D2 : D1
{
virtual void doX()
{
std::cout << "D2::doX()" << std::endl;
}
virtual void doY()
{
std::cout << "D2::doY()" << std::endl;
}
};
//From this point on you can do various things:
void driver()
{
Base* base = new D1;//
base->doX(); //Calls D1::doX()
D1* d1 = new D2;
d1->doX(); //Calls D2::doX()
}
// or...
void driver( Base* base )
{
//A way to replace Base with D1 with D2 depending
// on how driver was called.
}
//Finally, maybe you want a factory to create the correct
// derived type based on which factory was instantiated.
// Creates family of products, each item representing the base
// in it's hierarchy - only one shown here...
struct AbstractFactory
{
virtual std::unique_ptr<Base> create() const = 0;
protected:
virtual ~AbstractFactory(){}
};
struct D1Factory : AbstractFactory
{
//Doesn't matter if <Derived> is returned, because it adheres
// to interface of Base (isA base), and correct functions are
// found polymorphically
virtual std::unique_ptr<Base> create() const
{
return std::unique_ptr<Base>( new D1 );
}
};
struct D2Factory : AbstractFactory
{
//Doesn't matter if <Derived> is returned, because it adheres
// to interface of Base (isA base), and correct functions are
// found polymorphically
virtual std::unique_ptr<Base> create() const
{
return std::unique_ptr<Base>( new D2 );
}
};
void driver( const AbstractFactory& factory )
{
std::unique_ptr<Base> base( factory.create() );
base->doX();
base->doY();
//Memory deallocated automagically...
}
int main()
{
driver( D1Factory() );
driver( D2Factory() );
}
You'll see that this holds true to your quote. D2 replaces D1
seamlessly from the perspective of driver...
Please look at this code. It just reflects basic concept of what I want to do:
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
/* Some code I want to reuse */
Redefined();
}
virtual ~Base() {}
void Redefined() { val = 10; }
int val;
};
class Derived : public Base
{
public:
Derived() : Base() {}
~Derived() {}
void Redefined() { val = 25; }
};
int main()
{
Base* check = new Derived();
cout << check->val << endl;
system("pause");
return 0;
}
I want the val property of check object to be 25 instead of 10.
As you can see I have two classes. Base class constructor have some complex functionality, which I want Derived class to have in it's constructor as well. How can I change derived function Redefined so that I won't have to rewrite Derived constructor completely (in fact just copy-pasting the whole base class constructor code and replacing one single line of code - updated version of Redefined function)?
You can't really override a function that way. Normally you could use a virtual functions, but that doesn't work the way you want in the constructor.
A better way is to pass the value you want to the Base constructor:
class Base
{
public:
Base(int init_val = 10)
{
/* Some code I want to reuse */
val = init_val;
}
virtual ~Base() {}
int val;
};
class Derived : public Base
{
public:
Derived() : Base(25) {}
~Derived() {}
};
That way any derived class can pass its choice of value to the base class.
Based on comments above:
I would actually think that the correct solution is to have a "interface" type baseclass (that is, a baseclass with pure virtual functions, and the derived class actually implements the correct behaviour), and then let each class deal with constructing its own DirectX buffers. You may find that you need, say, 2-3 different derived classes that construct buffers in different ways, and then derive from those the classes that actually do the real work. I hope that makes sense.
Alternatively, you would be passing enough parameters to the base-class, such that the buffers can be constructed. But I think the first suggestion is a better choice.
I have an abstract type A, and two derived types A1 and A2.
I want to add a method M to class A, which takes a parameter of type A. But, I need ad hoc polymorphism.
Indeed, I need 3 implementations : A1::M(A1 a), A1::M(A2 a) and A2::(A1 a), A2::M(A2 a).
But I want an abstract way to call the method M with pointers of type A.
I could put all signatures declaration in class A, but it sucks.
Use simulated double dispatch.
class A {
public:
virtual void M(A &) = 0;
virtual void M(A1 &) = 0;
virtual void M(A2 &) = 0;
};
class A1 : public A {
public:
virtual void M(A &a) { a.M(*this); }
virtual void M(A1 &a) { std::cout << "A1 <- A1\n"; }
virtual void M(A2 &a) { std::cout << "A2 <- A1\n"; }
};
class A2 : public A {
public:
virtual void M(A &a) { a.M(*this); }
virtual void M(A1 &a) { std::cout << "A1 <- A2\n"; }
virtual void M(A2 &a) { std::cout << "A2 <- A2\n"; }
};
(See e.g. http://ideone.com/nycls.)
I don't think there is a way of avoiding the multiple overloads in the base class.
This is double dispatch. When you write:
A* p1;
A* p2;
p1->M(*p2);
should dispatch both on the type of *p1 and the type of *p2.
Before starting, you must realize that this means n^2 functions for
n different derived types. And that somewhere, someone must be aware
of all of the derived types (unless you can define some sort of
"default" implemenation for an unknown pair of types).
There are two ways of implementing this. The simplest, if the hierarchy
is closed (i.e. client code cannot introduce new derived classes) does
use a host of virtual functions in the base class—generally
protected, since they're not designed to be called outside the
hierarchy:
// Forward references needed for all derived classes...
class A1;
class A2;
// ...
class A
{
protectd:
virtual void doM(A1* arg) = 0;
virtual void doM(A2* arg) = 0;
// ...
public:
virtual void M(A& arg) = 0;
};
In the derived classes, the implementation of M is always the same:
void A1::M(A& arg)
{
arg.doM( this );
}
This is simple, and relatively efficient, but requires changes in the
abstract base and all of the derived classes (which have to implement
the new virtual function) each time you add a new derived class. It's
useful for closed hierarchies, however; I've used it in classes using
the strategy pattern for part of their behavior, where the various
strategies were all defined in the source file, and not exposed to the
clients (and the abstract base of the strategies was only forward
declared in the header, so no header changes were necessary if I added a
strategy).
A more general solution would involve an std::map, with a pair of
typeid as index. You can't use typeid directly, since it's not
copyable. C++11 provides a type_index to wrap it; if you're using an
older compiler, it's fairly trivial to implement one yourself. The
basic principle is something along the lines of (probably in A itself):
typedef std::pair<std::type_index, std::type_index> TypePairKey;
typedef void (*FuncPtr)( M* arg1, M* arg2 );
typedef std::unordered_map<TypePairKey, FuncPtr> DispatchMap;
static DispatchMap ourDispatchMap;
with:
void M( A& arg ) // NOT virtual !!!
{
DispatchMap::iterator entry
= ourDispatchMap.find(
DispatchMap::value_type( typeid( *this ), typeid( arg ) ) );
assert( entry != ourDispatchMap.end() );
// Or some default handling, maybe throw NotYetImplemented()
(*entry->second)( this, &arg );
}
The real problem comes with writing each of the individual functions and
inserting their addresses in the map (before first use). The functions
themselves, of course, can use dynamic_cast, or even static_cast, if
you can be sure that they will only be called from here, and they can be
friend(s) of the class(es) involved, but there are still
n2 of them. (One frequent solution is to make them
static members of one of the classes, and to have each derived class
define a static member of a type which does the registration of all of
the functions its responsible for.)
Why not do something like that?
void A1::M( A a )
{
if( dynamic_cast< A1* >( &a ) )
{
// do your A1::M1(A1 a) stuff
}
else
if( dynamic_cast< A2* >( &a ) )
{
// do your A1::M2(A2 a) stuff
}
else
{
throw std::logic_error( "Unsupported A type." );
}
}
And do equivalently for A2::M?
If you want polymorphic behavior - then all you need is one method in Base class A. You can then reimplement that method in A1, A2.
After that you can write:
A *a1 = new A1();
A *a2 = new A2();
a1->M(a2); //polymorphic behavior
If you make something like this:
struct A
{
virtual void M(A *a) {}
};
struct A1 : public A
{
virtual void M(A1 *a) {cout << "A1" << endl;}
virtual void M(A *a) {cout << "A" << endl;}
};
Then:
A1 * a1 = new A1();
a1->M(a1); //prints "A1"
A * a = a1;
a->M(a1); //prints "A"
I don't think this the behavior you want