Nico Schlömer Nico Schlömer - 3 months ago 14
C++ Question

Derived class calls parent's method

(Note: The corresponding gist is available here.)




I have a number of methods which are derived from
std::unary_function<K::Point_3, K::FT>
plus
typedef K::Point_3 Point;
(the underlying library CGAL requires it) – The class is called
Function
.

I now need to add a number of instances of derived classes (example:
MySphere
) to a
Function_vector
:



#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Implicit_to_labeling_function_wrapper.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;

class Function: public std::unary_function<K::Point_3, K::FT>
{
public:
typedef K::Point_3 Point; // necessary
// I'd rather not define operator() here
virtual K::FT operator()(K::Point_3 p) const {return 0.0;}
};

class MySphere: public Function
{
public:
virtual K::FT operator()(K::Point_3 p) const {return 3.14;}
};

typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<Function>
Function_wrapper;
typedef Function_wrapper::Function_vector Function_vector;

int main()
{
MySphere f1;

Function_vector v;
v.push_back(f1);

std::cout << f1(CGAL::ORIGIN) << std::endl; // MySphere::operator()
std::cout << v[0](CGAL::ORIGIN) << std::endl; // Function::operator() :(

return 0;
}


Problem:

Function_vector
does not accept pointers, so the actually abstract
Function
class cannot be virtual and needs to implement
operator()
from
std::unary_function
. When adding a
MySphere
instance to the
Function_vector
,
MySphere
gets cast into
Function
and
Function
's
operator()
is called, not
MySphere
's.

How to have
v[0]
call
MySphere::operator()
?

Answer

Since you put a Function object into the vector, and therefore have object slicing, you simply can't. Virtual function needs pointers or references to properly work with an inheritance tree.

The only advice I can give is that you rethink your design.

Comments