是否有任何与dynamic_cast错误处理相关的良好实践(除非您不必使用它)?我想知道我应该如何处理NULL和它可以抛出的bad_cast.我应该检查两者吗?如果我捕获bad_cast或检测到NULL,我可能无法恢复...现在,我正在使用assert检查dynamic_cast是否返回NULL值.你会在代码审查中接受这个解决方案吗?
我很想知道在使用动态强制转换RTTI禁用时(无论是-fno-rtti在GCC上还是/GR-在Visual Studio上)编译代码时会发生什么.编译器"退回"了static_cast吗?由于(至少在VS上)它只发出警告,编译的代码会做什么?
更具体地说,如果我在没有RTTI的情况下编译代码,那么可能会发生什么不好的事情我确信dynamic_cast没有错误(即dynamic_cast可以安全地替换为a static_cast),如下所示:
class A{ /*...*/ } ;
class B : public A {
int foo() { return 42 ;}
} ;
//...
A * myA = new B() ;
int bar = (dynamic_cast<B*>(myA))->foo() ;
Run Code Online (Sandbox Code Playgroud) 为什么我收到以下代码的以下错误?
1>C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(259): error C2683: 'dynamic_cast' : 'my_namespace::A' is not a polymorphic type
1> D:\[location]\[header_filename].h(35) : see declaration of 'my_namespace::A'
1> C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(522) : see reference to function template instantiation 'boost::shared_ptr<T>::shared_ptr<my_namespace::A>(const boost::shared_ptr<my_namespace::A> &,boost::detail::dynamic_cast_tag)' being compiled
1> with
1> [
1> T=my_namespace::B
1> ]
1> [location]\[source_filename].cpp(217) : see reference to function template instantiation 'boost::shared_ptr<T> boost::dynamic_pointer_cast<my_namespace::B,striker::A>(const boost::shared_ptr<my_namespace::A> &)' being compiled
1> with
1> [
1> T=my_namespace::B
1> ]
1>C:\Libs\boost_1_44\boost/smart_ptr/shared_ptr.hpp(260): fatal error C1903: unable to recover from previous error(s); stopping compilation
Run Code Online (Sandbox Code Playgroud)
C++代码或多或少如下:
#include <list>
#include …Run Code Online (Sandbox Code Playgroud) 我有一个类层次结构如下:
class BaseSession : public boost::enable_shared_from_this<BaseSession>
class DerivedSessionA : public BaseSession
class DerivedSessionB : public BaseSession
Run Code Online (Sandbox Code Playgroud)
在派生类函数中,我经常调用这样的函数:
Func(boost::dynamic_pointer_cast<DerivedSessionA>(shared_from_this()));
Run Code Online (Sandbox Code Playgroud)
由于我正在与shared_ptr管理会议,这工作正常.最近,我发现我shared_ptr对这种情况的使用不是最佳的.这是因为这些会话是单个对象,每个客户端维护一个套接字.如果重新连接套接字,则会话副本将成为僵尸.
作为解决方法,我开始通过shared_ptr引用传递而不是复制.这解决了僵尸问题.
理想情况下,我觉得我应该unique_ptr用来存储会话,然后将引用传递给其他函数.这打开了一大堆蠕虫.
如何将基类unique_ptr对象转换为派生类unique_ptr对象?unique_ptr以下行的版本是什么?
Func(boost::dynamic_pointer_cast<DerivedSessionA>(shared_from_this()));
Run Code Online (Sandbox Code Playgroud)
我只想要一个会话对象的副本,其他一切都应该是参考.
我有一段看起来像这样的代码:
TAxis *axis = 0;
if (dynamic_cast<MonitorObjectH1C*>(obj))
axis = (dynamic_cast<MonitorObjectH1C*>(obj))->GetXaxis();
Run Code Online (Sandbox Code Playgroud)
有时会崩溃:
Thread 1 (Thread -1208658240 (LWP 11400)):
#0 0x0019e7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1 0x048c67fb in __waitpid_nocancel () from /lib/tls/libc.so.6
#2 0x04870649 in do_system () from /lib/tls/libc.so.6
#3 0x048709c1 in system () from /lib/tls/libc.so.6
#4 0x001848bd in system () from /lib/tls/libpthread.so.0
#5 0x0117a5bb in TUnixSystem::Exec () from /opt/root/lib/libCore.so.5.21
#6 0x01180045 in TUnixSystem::StackTrace () from /opt/root/lib/libCore.so.5.21
#7 0x0117cc8a in TUnixSystem::DispatchSignals ()
from /opt/root/lib/libCore.so.5.21
#8 0x0117cd18 in SigHandler () from /opt/root/lib/libCore.so.5.21 …Run Code Online (Sandbox Code Playgroud) 假设我有以下类结构:
class Car;
class FooCar : public Car;
class BarCar : public Car;
class Engine;
class FooEngine : public Engine;
class BarEngine : public Engine;
Run Code Online (Sandbox Code Playgroud)
我们也给它Car一个句柄Engine.FooCar将使用a创建A ,FooEngine*并使用a BarCar创建BarEngine*.有没有办法安排事情,所以一个FooCar对象可以调用成员函数而FooEngine无需向下转换?
这就是为什么类结构按照现在的方式布局的原因:
Car都有Engine.此外,一个FooCar只会使用一个FooEngine.Engine,我宁愿不复制和粘贴.Engine了解它的函数Car.一旦我dynamic_cast在编写这段代码时输入,我就知道我可能做错了什么.有一个更好的方法吗?
更新:
根据目前给出的答案,我倾向于两种可能性:
Car提供一个纯虚getEngine()函数.这将允许FooCar并BarCar具有返回正确类型的实现Engine.Engine功能吸收到 …这不能用C++编译:
class A
{
};
class B : public A
{
};
...
A *a = new B();
B *b = dynamic_cast<B*>(a);
Run Code Online (Sandbox Code Playgroud) 我多次被告知(并且在实践中看到自己)使用dynamic_cast通常意味着糟糕的设计,因为它可以而且应该被虚函数替换.
例如,请考虑以下代码:
class Base{...};
class Derived:public Base{...};
...
Base* createSomeObject(); // Might create a Derived object
...
Base* obj = createSomeObject();
if(dynamic_cast<Derived*>(obj)){
// do stuff in one way
}
else{
// do stuff in some other way
}
Run Code Online (Sandbox Code Playgroud)
它可以很容易地看到,而不是编写动态类型转换,我们可以只添加一个虚函数doStuff()来Base和重新实现它Derived.
在这种情况下,我的问题是,为什么我们在语言中都有dynamic_cast?有没有一个例子,使用dynamic_cast是合理的?
根据我读到的,执行错误的运行时dynamic_cast可以抛出bad_cast异常或返回零.
如果你在指针上它会返回零,这是正确的吗?
即:
class Base { virtual void a(){} };
class Derived: public Base {};
int main () {
Base *base = new Base();
dynamic_cast<Derived*>(base);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并且它会在投射对象时抛出bad_cast异常?
即:
class Base { virtual void a(){} };
class Derived: public Base {};
int main () {
Base base;
Base& ref = base;
dynamic_cast<Derived&>(ref);
return 0;
}
Run Code Online (Sandbox Code Playgroud) c++ ×10
dynamic-cast ×10
casting ×2
inheritance ×2
rtti ×2
boost ×1
c++-faq ×1
car-analogy ×1
crash ×1
oop ×1
shared-ptr ×1
types ×1
unique-ptr ×1