C++ 有没有办法推断出物体的类型?
这可能是一个愚蠢的问题,我怀疑我知道答案(不),因为我似乎在这里碰壁 假设我有一个从某个类派生的对象集合:C++ 有没有办法推断出物体的类型?,c++,dispatch,C++,Dispatch,这可能是一个愚蠢的问题,我怀疑我知道答案(不),因为我似乎在这里碰壁 假设我有一个从某个类派生的对象集合: class BaseClass; class DerivedA: public BaseClass; class DerivedB: public BaseClass; class DerivedC: public BaseClass; std::vector<BaseClass> myCollection; 问题是,如果我访问集合中的单个项目并尝试调用“处理器”中的“doS
class BaseClass;
class DerivedA: public BaseClass;
class DerivedB: public BaseClass;
class DerivedC: public BaseClass;
std::vector<BaseClass> myCollection;
问题是,如果我访问集合中的单个项目并尝试调用“处理器”中的“doSomething”方法,它将无法决定使用哪种方法(afaik)。因此,我的问题是:有没有任何方法可以获取集合中具有正确派生类型的项?好的,是的,您应该如上所述使用多态性。如果你的函数需要处理2个对象,尽管它变得非常复杂 如果派生形成一个有限的集合,并且相互了解,则可以使用双重分派。这并不完美,但它解决了这个特殊情况
class DerivedA;
class DerivedB;
class DerivedC;
class BaseClass
{
public:
virtual ~BaseClass();
virtual void doSomethingWithBase( BaseClass & b2 ) = 0;
virtual void doSomethingWithDerivedA( DerivedA & da ) = 0;
virtual void doSomethingWithDerivedB( DerivedB & db ) = 0;
virtual void doSomethingWithDerivedC( DerivedC & dc ) = 0;
};
class DerivedA : public BaseClass
{
public:
void doSomethingWithBase( BaseClass & b2 )
{
b2.doSomethingWithDerivedA( *this );
}
void doSomethingWithDerivedA( DerivedA & da )
{
// implement for two DerivedA objects
}
void doSomethingWithDerivedB( DerivedB & db )
{
// implement for an A and B
}
void doSomethingWithDerivedC( DerivedC & dc )
{
// implement for an A and C
}
};
// implement DerivedB to call doSomethingWithDerivedB on its parameter
// implement DerivedC to call doSomethingWithDerivedC on its parameter.
你明白了。从你打电话的地方,你不需要知道你有哪两种类型,你也不需要实际查找。但是,如果你添加了更多的实现,你有很多代码要编辑,并且可以考虑某种查找表。
如果需要一个类来定义自己,可以使用某种虚拟id
class BaseClass
{
public:
virtual int id() const = 0;
};
然后让类显示它们的ID,并根据这些ID在表中找到处理这两个对象的处理程序。ID不必是int,它们可以是字符串,这样可以更容易地避免命名冲突,这比基类不知道其派生类或它们彼此知道并且可扩展的双重分派方法具有优势。您也不必处理每一对。好的,是的,您应该如上所述使用多态性。如果你的函数需要处理2个对象,尽管它变得非常复杂 如果派生形成一个有限的集合,并且相互了解,则可以使用双重分派。这并不完美,但它解决了这个特殊情况
class DerivedA;
class DerivedB;
class DerivedC;
class BaseClass
{
public:
virtual ~BaseClass();
virtual void doSomethingWithBase( BaseClass & b2 ) = 0;
virtual void doSomethingWithDerivedA( DerivedA & da ) = 0;
virtual void doSomethingWithDerivedB( DerivedB & db ) = 0;
virtual void doSomethingWithDerivedC( DerivedC & dc ) = 0;
};
class DerivedA : public BaseClass
{
public:
void doSomethingWithBase( BaseClass & b2 )
{
b2.doSomethingWithDerivedA( *this );
}
void doSomethingWithDerivedA( DerivedA & da )
{
// implement for two DerivedA objects
}
void doSomethingWithDerivedB( DerivedB & db )
{
// implement for an A and B
}
void doSomethingWithDerivedC( DerivedC & dc )
{
// implement for an A and C
}
};
// implement DerivedB to call doSomethingWithDerivedB on its parameter
// implement DerivedC to call doSomethingWithDerivedC on its parameter.
你明白了。从你打电话的地方,你不需要知道你有哪两种类型,你也不需要实际查找。但是,如果你添加了更多的实现,你有很多代码要编辑,并且可以考虑某种查找表。
如果需要一个类来定义自己,可以使用某种虚拟id
class BaseClass
{
public:
virtual int id() const = 0;
};
然后让类显示它们的ID,并根据这些ID在表中找到处理这两个对象的处理程序。ID不必是int,它们可以是字符串,这样可以更容易地避免命名冲突,这比基类不知道其派生类或它们彼此知道并且可扩展的双重分派方法具有优势。你也不必处理每一对。 < P>如果你要保留<代码> DOWOMENTHON/COMPUTE方法,这就是所谓的,而不是当前由C++支持的。p>
如果它是< BaseClass > <代码>的虚拟成员函数,那么,是的,它将被调用的对象上的Mulk C++多态性运行,但是它仍然不会自动推断出争论的类型。 为了解决这个问题,你可以做一些类似于前面链接中建议的事情
void collideWith(Thing& other) {
// dynamic_cast to a pointer type returns NULL if the cast fails
// (dynamic_cast to a reference type would throw an exception on failure)
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Asteroid-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Asteroid-Spaceship collision
} else {
// default collision handling here
}
}
void与(事物和其他)碰撞{
//如果转换失败,指针类型的动态\u转换将返回NULL
//(对引用类型的动态_转换将在失败时引发异常)
如果(小行星*小行星=动态)并提出整个问题的模拟。 < P>如果你要保留<代码> DOWOMENTHON/COMPUTE方法,这就是所谓的,而不是当前由C++支持的。
如果它是< BaseClass > <代码>的虚拟成员函数,那么,是的,它将被调用的对象上的Mulk C++多态性运行,但是它仍然不会自动推断出争论的类型。
为了解决这个问题,你可以做一些类似于前面链接中建议的事情
void collideWith(Thing& other) {
// dynamic_cast to a pointer type returns NULL if the cast fails
// (dynamic_cast to a reference type would throw an exception on failure)
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Asteroid-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Asteroid-Spaceship collision
} else {
// default collision handling here
}
}
void与(事物和其他)碰撞{
//如果转换失败,指针类型的动态\u转换将返回NULL
//(对引用类型的动态_转换将在失败时引发异常)
if(Asteroid*Asteroid=dynamic_)抛出并使整个问题变得毫无意义。如果您需要派生支持(以及随之而来的多态性)。您的向量应该是指针(以及智能指针);不是基类实例。您可能还对@WhozCraig感兴趣。感谢您的提醒,Karthik T解释了为什么我需要它,并且我没有意识到如果我使用实例,会发生对象切片。下面是C++11中的多分派示例:如果您想要派生支持(以及随之而来的多态性).你的向量应该是指针(和智能指针)Karthik,你可能还对@ HooZravigg的兴趣感兴趣,我解释了为什么我需要这个,我没有意识到如果我使用实例,对象切片会出现。下面是C++ 11中多个调度的例子:我考虑了双调度,但是如果我想把逻辑保存在SEPA中,它就不起作用了。速率类(在这种情况下,我这样做)。从理论上讲,您可以实现一个Trpple调度,据我所知,但这将导致更多的麻烦比它的价值:-(我确实考虑了一个双分派,但它不会起作用,如果我想保持逻辑在一个单独的类(在这种情况下,我这样做).理论上,据我所知,你可以实现三重调度,但这会带来更多的麻烦:-(虽然没有我希望的那么漂亮,但看起来这是做我想做的事情的最佳选择。谢谢你也解释了@WhozCraig的评论,直到我读到你的答案,我才意识到他为什么这么说:-)@uorbe001抱歉,我在评论中没有详细说明,但Karthik很好地填补了我在回答中留下的漏洞。很高兴你看到它是如何联系在一起的。它不像我希望的那么漂亮,但看起来这是做我想做的事情的最佳选择。谢谢你也解释了@WhozCraig的评论,我不知道为什么他一直这么说直到我