i have a class with the following structure:
class myClass
{
private:
int type;
classOne objectOne;
classTwo objectTwo;
public:
myClass(classOne object)
{
this->objectOne = object;
this->type = 0;
}
myClass(classTwo object)
{
this->objectTwo = object;
this->type = 1;
}
}
i now want a method returning an object of type classOne
if type is 0 and of type classTwo
if type is 1. I do not want two methods to achieve this. the classes have different structures.
Is this even possible? Any suggestions are appreciated :)
If they're completely different structures, with no common base then an alternative way you can return them from the same function is to use
void*
.However that's bad form in C++, usually indicating a design failure - either use two different functions, or use a common base class.
It's apples and oranges. If you put an apple into an recipe that calls for an orange it won't be the same recipe anymore.
I am not sure why you would not use templates for your case.
You can have something like below:
However, then this become trivial. Any more insight into what your use case is, such that you have to know the type?
Update: If the ClassType is going to be an Object, you can have a
const static int TypeID
member for the class, which is set at compile time. You can then use it determine the Type at runtime.The use of type-id is a sign that you need virtual functions for myClass. Even if the other two classes are totally independent, the fact that they are returned by the same function could easily make them inherit a base class. And also you can just return a pair containing class1, class2 and one of them can be null.
You can use Boost.Variant to do this. A variant can be constructed directly from any value convertible to one of its bounded types. Similarly, a variant can be assigned any value convertible to one of its bounded types. Heres how you could use it in your class:
It also provides a very convenient
boost::get
to retrieve the value from the variant. You can use that to supply code for each bounded type you have(ieclassOne
andclassTwo
). Here is an example:However, such code is quite brittle, and without careful attention will likely lead to the introduction of subtle logical errors detectable only at runtime. Thus, real-world use of variant typically demands an access mechanism more robust than
get
. For this reason, variant supports compile-time checked visitation viaapply_visitor
. Visitation requires that the programmer explicitly handle (or ignore) each bounded type. Failure to do so results in a compile-time error.Visitation of a variant requires a visitor object. Like this:
With the implementation of the above visitor, we can then apply it to
obj
, as seen in the following:Unless the two types are related (in which case you can create a function that will return a pointer/reference to the common ancestor) you cannot do that directly in C++.
C++ is a statically typed language, meaning that the type of every expression must be known at compile time, but you are trying to define a function whose return type depends on runtime values.
Depending on the particular problem to solve, there might be different approaches that you could take, including using type erasure (return a
boost::any
,boost::variant
or your own type-erasure).ClassOne and ClassTwo need to have the same return type then either via inheritance or composition. i.e ClassOne and ClassTwo need to be subclasses of the same super class OR they need to impl the same interface.