派生 class 调用父方法
Derived class calls parent's method
(注意: 对应的gist可用here。)
我有许多方法是从 std::unary_function<K::Point_3, K::FT>
和 typedef K::Point_3 Point;
派生的(底层库 CGAL 需要它)——class 被称为 Function
。
我现在需要将派生的 classes(示例:MySphere
)的多个实例添加到 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;
}
问题:
Function_vector
不接受指针,所以实际上抽象的Function
class不能是虚的,需要从std::unary_function
实现operator()
。将 MySphere
实例添加到 Function_vector
时,MySphere
被转换为 Function
并调用 Function
的 operator()
,而不是 MySphere
的。
如何让 v[0]
调用 MySphere::operator()
?
由于您将 Function
对象放入向量中,因此有 object slicing,您根本做不到。虚函数需要 指针或引用才能正确使用继承树。
我能给的唯一建议是重新考虑您的设计。
作为一种解决方法,可以创建另一个包装器 MyFun
并将其送入 Function
à la
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
#include <memory>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
class MyFun: public std::unary_function<K::Point_3, K::FT>
{
public:
virtual K::FT operator()(K::Point_3 p) const = 0;
};
class MySphere: public MyFun
{
public:
virtual K::FT operator()(K::Point_3 p) const {return 3.14;}
};
class Function: public std::unary_function<K::Point_3, K::FT>
{
public:
typedef K::Point_3 Point;
explicit Function(std::shared_ptr<MyFun> fun):
fun_(fun)
{
}
virtual K::FT operator()(K::Point_3 p) const {
return fun_->operator()(p);
}
private:
std::shared_ptr<MyFun> fun_;
};
typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<Function> Function_wrapper;
typedef Function_wrapper::Function_vector Function_vector;
int main()
{
auto f1 = std::make_shared<MySphere>();
Function_vector v;
v.push_back(Function(f1));
std::cout << (*f1)(CGAL::ORIGIN) << std::endl;
std::cout << v[0](CGAL::ORIGIN) << std::endl;
return 0;
}
(注意: 对应的gist可用here。)
我有许多方法是从 std::unary_function<K::Point_3, K::FT>
和 typedef K::Point_3 Point;
派生的(底层库 CGAL 需要它)——class 被称为 Function
。
我现在需要将派生的 classes(示例:MySphere
)的多个实例添加到 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;
}
问题:
Function_vector
不接受指针,所以实际上抽象的Function
class不能是虚的,需要从std::unary_function
实现operator()
。将 MySphere
实例添加到 Function_vector
时,MySphere
被转换为 Function
并调用 Function
的 operator()
,而不是 MySphere
的。
如何让 v[0]
调用 MySphere::operator()
?
由于您将 Function
对象放入向量中,因此有 object slicing,您根本做不到。虚函数需要 指针或引用才能正确使用继承树。
我能给的唯一建议是重新考虑您的设计。
作为一种解决方法,可以创建另一个包装器 MyFun
并将其送入 Function
à la
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
#include <memory>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
class MyFun: public std::unary_function<K::Point_3, K::FT>
{
public:
virtual K::FT operator()(K::Point_3 p) const = 0;
};
class MySphere: public MyFun
{
public:
virtual K::FT operator()(K::Point_3 p) const {return 3.14;}
};
class Function: public std::unary_function<K::Point_3, K::FT>
{
public:
typedef K::Point_3 Point;
explicit Function(std::shared_ptr<MyFun> fun):
fun_(fun)
{
}
virtual K::FT operator()(K::Point_3 p) const {
return fun_->operator()(p);
}
private:
std::shared_ptr<MyFun> fun_;
};
typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<Function> Function_wrapper;
typedef Function_wrapper::Function_vector Function_vector;
int main()
{
auto f1 = std::make_shared<MySphere>();
Function_vector v;
v.push_back(Function(f1));
std::cout << (*f1)(CGAL::ORIGIN) << std::endl;
std::cout << v[0](CGAL::ORIGIN) << std::endl;
return 0;
}