我dynamic_cast对C++中的关键字很困惑.
struct A {
virtual void f() { }
};
struct B : public A { };
struct C { };
void f () {
A a;
B b;
A* ap = &b;
B* b1 = dynamic_cast<B*> (&a); // NULL, because 'a' is not a 'B'
B* b2 = dynamic_cast<B*> (ap); // 'b'
C* c = dynamic_cast<C*> (ap); // NULL.
A& ar = dynamic_cast<A&> (*ap); // Ok.
B& br = dynamic_cast<B&> (*ap); // Ok.
C& cr = dynamic_cast<C&> …Run Code Online (Sandbox Code Playgroud) 我想为java变量进行动态转换,转换类型存储在不同的变量中.
这是常规铸造:
String a = (String) 5;
Run Code Online (Sandbox Code Playgroud)
这就是我要的:
String theType = 'String';
String a = (theType) 5;
Run Code Online (Sandbox Code Playgroud)
可能吗?如果是这样怎么样?谢谢!
我正在尝试用我收到的hashMap填充一个类.
这是构造函数:
public ConnectParams(HashMap<String,Object> obj) {
for (Map.Entry<String, Object> entry : obj.entrySet()) {
try {
Field f = this.getClass().getField(entry.getKey());
f.set(this, entry.getValue()); /* <= CASTING PROBLEM */
} catch (NoSuchFieldException ex) {
log.error("did not find field '" + entry.getKey() + '"');
} catch (IllegalAccessException ex) {
log.error(ex.getMessage());
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是一些类变量是Double类型,如果接收到数字3,它将其视为Integer,我有类型问题.
在C++中,T q = dynamic_cast<T>(p);构造执行指向p其他指针类型的指针的运行时强制转换,该指针类型T必须出现在动态类型的继承层次结构*p中才能成功.这一切都很好,很好.
但是,也可以执行,它只dynamic_cast<void*>(p)返回指向"最派生对象"的指针(参见C++ 11中的5.2.7 :: 7).我知道这个功能可能在动态转换的实现中免费提供,但它在实践中是否有用?毕竟,它的返回类型充其量void*只是,这有什么用呢?
出于检查空指针的习惯,我有时写道:
MyClass * c = someBasePtr ? dynamic_cast<MyClass*>(someBasePtr) : 0;
if (c) {...
Run Code Online (Sandbox Code Playgroud)
实际上,在传递给动态强制转换之前检查空指针,并检查返回.
然后我读了MSDN文档
通过dynamic_cast将空指针值转换为目标类型的空指针值.
然后我可以安全地删除?:构造.这个C++是可移植的吗?
这样新代码就可以了
MyClass * c = dynamic_cast<MyClass*>(someBasePtr);
if (c) {...
Run Code Online (Sandbox Code Playgroud)
当然假设someBasePtr是null或有效,即不是疯狂指向垃圾......
我正在检查dynamic_cast的行为,发现当它失败时,仅当目标是引用类型时才抛出std :: bad_cast异常.如果目标是指针类型,则不会从强制转换中抛出异常.这是我的示例代码:
class A
{
public:
virtual ~A()
{
}
};
class B : public A
{
};
int main()
{
A* p = new A;
//Using reference
try
{
B& b = dynamic_cast<B&>(*p);
}
catch(std::bad_cast exp)
{
std::cout<<"Caught bad cast\n";
}
//Using pointer
try
{
B* pB = dynamic_cast<B*>(p);
if( pB == NULL)
{
std::cout<<"NULL Pointer\n";
}
}
catch(std::bad_cast exp)
{
std::cout<<"Caught bad cast\n";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是"Caught bad cast"和"NULL pointer".代码使用VS2008编译.这是正确的行为吗?如果是,那为什么会有区别?
在阅读问题之前:
这个问题不是关于它的使用有多大dynamic_cast.它只是它的表现.
我最近开发了一个dynamic_cast经常使用的设计.
在与同事讨论时,几乎每个人都说dynamic_cast不应该使用它,因为它的表现不好(这些是有不同背景的同事,在某些情况下彼此不认识.我在一家大公司工作)
我决定测试这种方法的性能而不是仅仅相信它们.
使用以下代码:
ptime firstValue( microsec_clock::local_time() );
ChildObject* castedObject = dynamic_cast<ChildObject*>(parentObject);
ptime secondValue( microsec_clock::local_time() );
time_duration diff = secondValue - firstValue;
std::cout << "Cast1 lasts:\t" << diff.fractional_seconds() << " microsec" << std::endl;
Run Code Online (Sandbox Code Playgroud)
上面的代码使用boost::date_timeLinux上的方法来获取可用的值.
我已经完成dynamic_cast了三合一执行,测量它们的代码是相同的.
执行结果如下:
Cast1持续时间:74
microsec Cast2持续时间:2
microsec Cast3持续时间:1微秒
第一次施法总是花费74-111微秒,同样执行的以下演员需要1-3微秒.
最后我的问题
是:dynamic_cast真的表现不好吗?
根据测试结果,它没有.我的测试代码是否正确?
为什么这么多开发人员认为如果不是这么慢呢?
考虑这个简单的层次
class Base { public: virtual ~Base() { } };
class Derived : public Base { };
Run Code Online (Sandbox Code Playgroud)
试图向下转换Base* p到Derived*可能使用dynamic_cast<Derived*>(p).我曾经dynamic_cast通过将vtable指针p与Derived对象中的指针进行比较来思考作品.
但是,如果我们从中衍生出另一个类Derived呢?我们现在有:
class Derived2 : public Derived { };
Run Code Online (Sandbox Code Playgroud)
在这种情况下:
Base* base = new Derived2;
Derived* derived = dynamic_cast<Derived*>(base);
Run Code Online (Sandbox Code Playgroud)
我们仍然得到一个成功的向下转换,即使vtable指针in Derived2与vtable指针无关Derived.
它是如何实际工作的?如何dynamic_cast知道是否Derived2派生自Derived(如果Derived在不同的库中声明的话)?
我正在寻找关于它如何实际工作的具体细节(最好是在海湾合作委员会,但其他人也很好).这个问题是不是一个重复这个问题(没有指明它是如何工作).
对于我的GUI API,它适用于各种后端(sdl,gl,d3d等),我想动态地将泛型类型图像转换为它可能发生的任何形式.
所以最重要的是,我将每秒做大约20*60fps的动态演员表.
动态演员有多贵?我是否会注意到它对性能有明显的负面影响?我还有哪些替代品可以保持可接受的性能水平?
5.2.7/7说的内容如下:
如果
T是"指向cv void",则结果是指向由其指向的派生类最多的指针x.
这个synatx有什么好的应用?什么时候应该dynamic_cast<void*>使用?