C ++ calling slices object of base class method

I have something like this:

#include <iostream> class X; class A { public: virtual void bar(X &x); }; class B : public A { public: }; class X { public: void foo(A &a) { std::cout << "foo A" << std::endl; } void foo(B &b) { std::cout << "foo B" << std::endl; } }; void A::bar(X &x) { x.foo(*this); } int main(int argc, char **argv) { X x; B b; b.bar(x); return 0; } 

Compile it and run it, you will get:

 # ./a.out foo A # 

I believe this is because the object is sliced ​​by clicking on A. How can I avoid this in order to get

 foo B 

without implementing the method in B or using some oddity, for example Curiously repeating pattern template ?

+2
source share
1 answer

No slicing happens here, because you carefully pass objects by reference; slicing requires manipulating an object by value.

The effect is due to overload resolution, which is performed statically (i.e. at compile time). When C ++ compiles this member function

 void A::bar(X &x) { x.foo(*this); } 

he needs to decide, at compile time, which of the two overloads to choose. The solution is simple: the compiler knows that *this is of type A , so it calls the void foo(A &a) function.

You cannot make it work without implementing the same method in B * using templates or by implementing your own dispatch scheme with function objects or lambdas.

* and in this case, you will get an almost classic implementation of C ++ Visitor Pattern , a Double Sending implementation technique.

+5
source

Source: https://habr.com/ru/post/984785/


All Articles