我有一个具有以下结构的课程:
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;
}
}
我现在想要一个方法,如果type为0,则返回类型classOne
的对象,如果type为1,则返回类型classTwo
。我不希望有两种方法来实现这一点。这些课程有不同的结构。
这甚至可能吗?任何建议表示赞赏:)
答案 0 :(得分:2)
除非这两种类型相关(在这种情况下你可以创建一个返回指向共同祖先的指针/引用的函数),你不能直接在C ++中这样做。
C ++是一种静态类型语言,这意味着必须在编译时知道每个表达式的类型,但是您要尝试定义一个返回类型取决于运行时值的函数。
根据要解决的特定问题,您可以采用不同的方法,包括使用类型擦除(返回boost::any
,boost::variant
或您自己的类型擦除)。
答案 1 :(得分:2)
您可以使用Boost.Variant执行此操作。变体可以直接从可转换为其有界类型之一的任何值构造。类似地,可以为变体分配任何可转换为其有界类型之一的值。以下是你如何在课堂上使用它:
class myClass
{
private:
boost::variant<classOne, classTwo> obj;
public:
myClass(classOne object) : obj(object)
{
}
myClass(classTwo object) : obj(object)
{
}
};
它还提供了非常方便的boost::get
来从变体中检索值。
您可以使用它为您拥有的每个有界类型提供代码(即classOne
和classTwo
)。这是一个例子:
if (classOne * x = boost::get<classOne>(&obj))
{
//Code for classOne
}
else if (classTwo * x = boost::get<classTwo>(&obj)
{
//Code for classTwo
}
然而,这样的代码非常脆弱,如果不仔细注意,可能会导致引入仅在运行时可检测到的细微逻辑错误。因此,变体的实际使用通常要求访问机制比get
更健壮。因此,variant支持通过apply_visitor
进行编译时检查的访问。访问要求程序员明确处理(或忽略)每个有界类型。如果不这样做会导致编译时错误。
访问变体需要访问者对象。像这样:
class object_visitor
: public boost::static_visitor<>
{
public:
void operator()(classOne & x) const
{
//Code for classOne
}
void operator()(classTwo & x) const
{
//Code for classTwo
}
};
随着上述访问者的实施,我们可以将其应用于obj
,如下所示:
boost::apply_visitor( object_visitor(), obj );
答案 2 :(得分:1)
ClassOne和ClassTwo需要具有相同的返回类型,然后通过继承或组合。即ClassOne和ClassTwo需要是同一个超类的子类,或者需要使用相同的接口。
答案 3 :(得分:1)
我不确定为什么你不会为你的案子使用模板。
您可以拥有以下内容:
template <class ClassType>
class myClass
{
private:
int type;
ClassType object;
public:
myClass(ClassType object_in)
{
this->object = object_in;
/*
C++ doesn't support reflection so I don't think there
is a robust way of doing the following at runtime.
*/
type = /* Get Type at runtime */;
}
/*
Have another method which return object in a straigtforward way.
*/
};
然而,这变得微不足道。更深入了解您的用例是什么,以便您必须知道类型?
<强>更新强>
如果ClassType将成为Object,则可以为该类设置const static int TypeID
成员,该成员在编译时设置。然后,您可以使用它在运行时确定类型。
答案 4 :(得分:0)
如果它们是完全不同的结构,没有共同的基础,那么你可以从同一个函数返回它们的另一种方法是使用void*
。
然而这是C ++中的错误形式,通常表示设计失败 - 要么使用两个不同的函数,要么使用公共基类。
这是苹果和橘子。如果你把一个苹果放入需要橙色的食谱中,它就不再是同一个配方了。
答案 5 :(得分:0)
使用type-id表示您需要myClass的虚函数。即使其他两个类完全独立,它们由同一个函数返回的事实也很容易使它们继承一个基类。而且你也可以返回一个包含class1,class2的对,其中一个可以为null。
答案 6 :(得分:0)
第一个问题是如何确定返回了哪种类型的类。我认为可以返回指向此类型结构的指针
struct res {
myClass* c1;
ClassOne* c2;
} ;
未选择类的字段为NULL,另一个指向对象。