以下代码解释了问题.填写same_sub_class以检测到虚拟基类A的两个指针实际上是否是同一个具体类.
struct A {
...
}:
struct B : public A {
...
}:
struct C : public A {
...
}
bool same_sub_class(A * a1, A * a2){
// Fill this in to return true if a1 and a2 are
// of the same concrete class
}
Run Code Online (Sandbox Code Playgroud)
编辑:
当我查看我的应用程序时,我需要一些与上面略有不同的东西.我需要能够通过type_id对实例进行分组.
仅供参考.我有一个迷你符号algerbra系统,所以要进行操作,有时需要知道类类型进行排序和重新排列表达式很重要.
所以给出了一个指针向量,用于实例说明如何通过type_id对它们进行分组.我要么需要能够散列type_id,要么为每个类生成一个唯一的整数.
我知道dynamic_cast在类层次结构中进行"交叉投射" 是合法的.例如,如果我有类似这样的类:
A B
\ /
C
Run Code Online (Sandbox Code Playgroud)
如果我有一个A*指向类型对象的指针C,那么我可以使用
A* aPtr = /* ... something that produces a C* ... */
B* bPtr = dynamic_cast<B*>(aPtr);
Run Code Online (Sandbox Code Playgroud)
获取指向我指向的B基础对象的C指针.
我提到这一点的原因是,在我写上面的代码的时候,它可能是编译器目前还没有看到的定义C,即使它看到的A和B.这意味着编译器可能没有检测到A和之间的任何类型的连接B,但它仍然必须编译代码,因为它可能C存在类似的存在以及dynamic_cast在某些情况下成功.
问题是这意味着我可能会意外地交叉转换为错误类型的对象.假设我有类似这样的类:
A B D
\ /
C
Run Code Online (Sandbox Code Playgroud)
在这里,D是一些随机无关的类.如果我尝试写这样的东西:
A* aPtr = /* ... get a C* pointer ... */
D* dPtr = dynamic_cast<D*>(aPtr);
Run Code Online (Sandbox Code Playgroud)
那么这dynamic_cast将始终在运行时失败,因为有连接没有可能的方式A和 …
不久之前,我发现了一篇非常有趣的论文,关于C++中dynamic_cast的非常整洁的性能升级:http://www2.research.att.com/~bs/fast_dynamic_casting.pdf.
基本上,它使得C++中的dynamic_cast比继承树中的传统研究更快.如该论文所述,该方法提供了快速,恒定时间的动态铸造算法.
本文发表于2005年.现在,我想知道这项技术是否曾在某处实施过,或者是否有计划在任何地方实施?
我写了一个简单的例子,它使用基类接口和dynamic_cast以及非虚函数调用来估计调用虚函数的平均时间.就这个:
#include <iostream>
#include <numeric>
#include <list>
#include <time.h>
#define CALL_COUNTER (3000)
__forceinline int someFunction()
{
return 5;
}
struct Base
{
virtual int virtualCall() = 0;
virtual ~Base(){};
};
struct Derived : public Base
{
Derived(){};
virtual ~Derived(){};
virtual int virtualCall(){ return someFunction(); };
int notVirtualCall(){ return someFunction(); };
};
struct Derived2 : public Base
{
Derived2(){};
virtual ~Derived2(){};
virtual int virtualCall(){ return someFunction(); };
int notVirtualCall(){ return someFunction(); };
};
typedef std::list<double> Timings;
Base* createObject(int i)
{
if(i …Run Code Online (Sandbox Code Playgroud) 我在我正在开发的代码库中遇到了很多dyn_cast.
它与dynamic_cast是一回事吗?还是别的什么?我搜索了一下但找不到太多信息..
我已经阅读了几个关于C++动态转换的线程,所有人都声称它表明设计不好.在其他语言中,我在检查对象的类型时从未考虑过太多.我从不使用它作为多态性的替代,只有当强耦合看起来完全可以接受时.我经常遇到的这些情况之一:有一个列表(我在C++中使用std :: vector)的对象,都是从一个公共基类派生的.该列表由一个允许知道不同子类的对象管理(通常它是管理对象类中私有类的一个小层次).通过将它们保存在单个列表(数组,向量,...)中,我仍然可以从多态中受益,但是当一个操作意图作用于特定子类的对象时,我使用动态转换或类似的东西.
如果没有我缺少的动态强制转换或类型检查,是否存在针对此类问题的不同方法?我真的好奇那些不惜一切代价避免这些的程序员会如何处理它们.
如果我的描述过于抽象,我可以在C++中编写一个简单的例子(编辑:见下文).
class EntityContacts {
private:
class EntityContact {
private:
virtual void someVirtualFunction() { }; // Only there to make dynamic_cast work
public:
b2Contact* m_contactData;
};
class InternalEntityContact : public EntityContact {
public:
InternalEntityContact(b2Fixture* fixture1, b2Fixture* fixture2){
m_internalFixture1 = fixture1;
m_internalFixture2 = fixture2;
};
b2Fixture* m_internalFixture1;
b2Fixture* m_internalFixture2;
};
class ExternalEntityContact : public EntityContact {
public:
ExternalEntityContact(b2Fixture* internalFixture, b2Fixture* externalFixture){
m_internalFixture = internalFixture;
m_externalFixture = externalFixture;
};
b2Fixture* m_internalFixture;
b2Fixture* m_externalFixture;
};
PhysicsEntity* m_entity;
std::vector<EntityContact*> m_contacts;
public: …Run Code Online (Sandbox Code Playgroud) 有人说 the use of dynamic_cast often means bad design and dynamic_cast can be replaced by virtual functions
dynamic_cast认为是糟糕的设计?假设我有函数名func(Animal* animal, int animalType),func中的实现如下:
bool func(Animal* animal, int animalType)
{
...
/* Animal is the base class of Bear, Panda, Fish ....
dynamic_cast animal to real animals(Bear, Panda, Fish...)
according to animalType. Do some processing with this specific
type of animal, using its additional information beyond base
class Animal. */
}
Run Code Online (Sandbox Code Playgroud)这种情况是否正确使用dynamic_cast?
在最后两行以下程序,static_cast<void*>并dynamic_cast<void *>表现不同.据我所知,的结果dynamic_cast<void*>总是解析为完整的对象的地址.所以它以某种方式使用RTTI.谁能解释一下编译器如何使用RTTI两者之间的区分.
#include <iostream>
using namespace std;
class Top {
protected:
int x;
public:
Top(int n) { x = n; }
virtual ~Top() {}
friend ostream& operator<<(ostream& os, const Top& t) {
return os << t.x;
}
};
class Left : virtual public Top {
protected:
int y;
public:
Left(int m, int n) : Top(m) { y = n; }
};
class Right : virtual public Top {
protected:
int z;
public:
Right(int m, …Run Code Online (Sandbox Code Playgroud) 如图所示在这里,人们可以使用dynamic_cast来检测已删除的指针:
#include <iostream>
using namespace std;
class A
{
public:
A() {}
virtual ~A() {}
};
class B : public A
{
public:
B() {}
};
int main()
{
B* pB = new B;
cout << "dynamic_cast<B*>( pB) ";
cout << ( dynamic_cast<B*>(pB) ? "worked" : "failed") << endl;
cout << "dynamic_cast<B*>( (A*)pB) ";
cout << ( dynamic_cast<B*>( (A*)pB) ? "worked" : "failed") << endl;
delete pB;
cout << "dynamic_cast<B*>( pB) ";
cout << ( dynamic_cast<B*>(pB) …Run Code Online (Sandbox Code Playgroud) 这个代码合法吗?
class Base1 {
};
class Base2 {
public:
virtual ~Base2() {
if (!dynamic_cast<Base1*>(this))
std::cout << "aaaa" << std::endl;
}
Base2() {
}
};
class MyClass: public Base1, public Base2 {
public:
MyClass() {
}
virtual ~MyClass() {
std::cout << "bbb" << std::endl;
}
};
int main() {
MyClass s;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我看到了两张照片,但我应该只看到一张。我猜动态演员是错误的。可以做这种检查吗?
c++ polymorphism destructor dynamic-cast multiple-inheritance
c++ ×10
dynamic-cast ×10
performance ×2
casting ×1
cross-cast ×1
destructor ×1
dispatch ×1
llvm ×1
oop ×1
polymorphism ×1
rtti ×1
vtable ×1