我有一个问题,但它不仅限于C++.如何从一个函数返回完全不同的类?
f() {
in case one: return A;
in case two: return B;
in case three: return C;
}
Run Code Online (Sandbox Code Playgroud)
例如,我在空间中有两个球,根据位置和大小,两个球相互交叉有三种情况,即非交点,点,a和圆.如何在一个函数中返回不同的类?
谢谢.
Man*_*uel 30
如果你能买得起Boost,那么这听起来就像是Boost.Variant的完美应用.
struct NoIntersection {
// empty
};
struct Point {
// whatever
};
struct Circle {
// whatever
};
typedef boost::variant<NoIntersection, Point, Circle> IntersectionResult;
IntersectionResult intersection_test() {
if(some_condition){
return NoIntersection();
}
if(other_condition){
return Point(x, y);
}
if(another_condition){
return Circle(c, r);
}
throw std::runtime_error("unexpected");
}
Run Code Online (Sandbox Code Playgroud)
然后,您使用静态访问者处理结果:
struct process_result_visitor : public boost::static_visitor<> {
void operator()(NoIntersection) {
std::cout << "there was no intersection\n";
}
void operator()(Point const &pnt) {
std::cout << "there was a point intersection\n";
}
void operator()(Circle const &circle) {
std::cout << "there was a circle intersection\n";
}
};
IntersectionResult result = intersection_test();
boost::apply_visitor(process_result_visitor(), result);
Run Code Online (Sandbox Code Playgroud)
编辑:访客类必须来自boost::static_visitor
更新:在一些批评意见的提示下,我写了一些基准程序.比较了四种方法:
boost::variantboost::any当我使用默认优化(VC08)在发布模式下编译时,这些是我的家用计算机中的结果:
使用boost :: variant进行测试需要0.011微秒
用union测试需要0.012微秒
用层次结构测试花了0.227微秒
使用boost :: any测试需要0.188微秒
使用boost::variant比联合更快并且引导(IMO)到最优雅的代码.我猜测类层次结构方法的极差性能是由于需要使用动态内存分配和动态调度.boost::any既不快也不优雅,所以我不会考虑这个任务(它有其他应用程序)
ant*_*res 13
要返回的类应该从公共基类派生.因此,您可以返回基本类型.例如(这不是代码,只是标记模式,如果您的语言支持此抽象或抽象类,则可以使用接口.如果使用C++,则必须返回公共类的指针):
class A : public Common
{
..
}
class B : public Common
{
..
}
class C : public Common
{
..
}
Common f() {
in case one: return A;
in case two: return B;
in case three: return C;
}
Run Code Online (Sandbox Code Playgroud)
除了@Manuel的Boost.Variant建议之外,请看看Boost.Any:具有与Boost.Variant类似的目的,但有不同的权衡和功能.
boost :: any是无界的(可以包含任何类型),而boost :: variant是有界的(支持的类型以变体类型编码,因此它只能包含这些类型的值).
// from Beyond the C++ Standard Library: An Introduction to Boost
// By Björn Karlsson
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include "boost/any.hpp"
class A {
public:
void some_function() { std::cout << "A::some_function()\n"; }
};
class B {
public:
void some_function() { std::cout << "B::some_function()\n"; }
};
class C {
public:
void some_function() { std::cout << "C::some_function()\n"; }
};
int main() {
std::cout << "Example of using any.\n\n";
std::vector<boost::any> store_anything;
store_anything.push_back(A());
store_anything.push_back(B());
store_anything.push_back(C());
// While we're at it, let's add a few other things as well
store_anything.push_back(std::string("This is fantastic! "));
store_anything.push_back(3);
store_anything.push_back(std::make_pair(true, 7.92));
void print_any(boost::any& a);
// Defined later; reports on the value in a
std::for_each(
store_anything.begin(),
store_anything.end(),
print_any);
}
void print_any(boost::any& a) {
if (A* pA=boost::any_cast<A>(&a)) {
pA->some_function();
}
else if (B* pB=boost::any_cast<B>(&a)) {
pB->some_function();
}
else if (C* pC=boost::any_cast<C>(&a)) {
pC->some_function();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2125 次 |
| 最近记录: |