Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
129 views
in Technique[技术] by (71.8m points)

c++ - How to return different classes from one function?

I have a question, though it is not limited to C++. How to return totally different class from one function?

f() {

in case one: return A;
in case two: return B;
in case three: return C;


}

For example, I have two balls in the space, according to the position and the size, there are three situations for the two balls to intersect with each other, i.e, non-intersection, at point, a and circle. How can I return different class in one function?

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you can afford Boost then this sounds like a perfect application for 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");
}

You then process your result with a static visitor:

 struct process_result_visitor : public boost::static_visitor<> {
    
     void operator()(NoIntersection) {
        std::cout << "there was no intersection
";
     }
     void operator()(Point const &pnt) {
        std::cout << "there was a point intersection
";
     }
     void operator()(Circle const &circle) {
        std::cout << "there was a circle intersection
";
     }
 };

 IntersectionResult result = intersection_test();
 boost::apply_visitor(process_result_visitor(), result);

EDIT: The visitor class must derive from boost::static_visitor

UPDATE: Prompted by some critical comments I've written a little benchmark program. Four approaches are compared:

  • boost::variant
  • union
  • class hierarchy
  • boost::any

These are the results in my home computer, when I compile in release mode with default optimizations (VC08):

test with boost::variant took 0.011 microseconds

test with union took 0.012 microseconds

test with hierarchy took 0.227 microseconds

test with boost::any took 0.188 microseconds

Using boost::variant is faster than a union and leads (IMO) to the most elegant code. I'd guess that the extremely poor performance of the class hierarchy approach is due to the need to use dynamic memory allocations and dynamic dispatch. boost::any is neither fast nor especially elegant so I wouldn't consider it for this task (it has other applications though)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...