C++强制转换为派生指针或设计错误
C++ cast to derived pointer or design mistake
我有一个关于多态性的问题
using namespace std;
class Base {
public:
Base(int v) { u = v; };
virtual ~Base(){};
int u;
void f() { /* operations on u */ };
};
template<class T>
class Derived: public Base {
public:
T t;
Derived() { }
void g() { std::cout << u; /* operations on t and u */ }
};
int main() {
Base *b = new Base(1);
b->f();
if (b->u == 1) {
Derived<int> *d = dynamic_cast<Derived<int> *>(b);
d->g();
}
return 0;
}
使用 d->g() 将存在段错误。 是否可以在强制转换后访问派生对象中的 u? 该程序的目的是构造一个未知类型的类(有关这方面的信息只有在构造了类对象之后才能获得,例如读取jpg文件的类,事先不知道深度信息)。 还是有针对这类问题的设计模式? 感谢您的任何提示。
您的代码段错误不是因为*b
中没有Base::u
,而是因为d
是一个nullptr
,取消引用它会调用未定义的行为。根据规范,dynamic_cast<T*>(p)
为您提供
- 指向属于
*p
T
对象的指针(如果有)或其他 nullptr
.
由于b
不指向类型为 Derived<int>
的对象,因此您可以得到nullptr
。稍后,当您尝试使用该nullptr
时,您的程序会出现段错误。
请注意,如果dynamic_cast
引用,则行为会有所不同。 dynamic_cast<T&>(r)
意志
- 为您提供对属于
r
的T
对象的引用(其中r
是引用)或 - 如果没有此类对象,则
throw
类型std::bad_cast
的例外。
因此,您通常以以下任一方式使用 dynamic_cast
。
-
如果你想测试一个对象的动态类型,并在它达到一定
class
时用它做一些事情:if (auto d = dynamic_cast<D*>(b)) { // We have a D object here (d != nullptr), use it. d->use(); } else { // We don't have a D object (d == nullptr) here. }
-
如果您(认为您)确定指针指向(动态)类型的对象
D
:dynamic_cast<D&>(*b).use();
在您的情况下,您似乎有一个约定,即b->u == 1
应该以某种方式暗示*b
的动态类型是Derived<int>
的,因此您可以考虑引用dynamic_cast
。(如果没有别的,它会给你一个比这里的"分段错误"更有用的错误消息。当然,现在您知道dynamic_cast
的行为方式,您可以摆脱该"约定"并直接通过指向指针dynamic_cast
测试动态类型。无论如何,您首先必须解决Sam Varshavchik的答案中描述的问题。
查看 cppreference.com 以获取有关dynamic_cast
的更多信息。
不,这是不可能的。
这是因为您构造了 Base
的实例,而不是 Derived
的实例。您可能打算这样做:
Base *b = new Derived<int>();
但这也不起作用,因为Base
没有默认构造函数。
您将永远无法使用此代码实例化任何Derived<T>
,因为Derived
尝试使用 Base
的默认构造函数,但它没有。
dynamic_cast<T>
不用于凭空创建附加到现有类的新实例。它用于解析超类或子类的现有实例,该实例与动态强制转换的实例所属的类相关。
- 删除指向指针的指针是运行时错误吗
- c++中的指针和运行时错误
- 运行几次后合并段错误C++(指针算术)
- LinkedList实现C 错误指针间接
- 虚幻引擎 4.18.0,VS2017,不允许指向不完整类类型的错误指针
- Xcode 错误:指针和双精度之间的比较
- 未分配正在释放的本机node.js插件错误指针
- 错误指针:解析令牌时无法计算表达式
- C++-va_list错误指针
- 为什么我收到错误" (指针的名称)不是模板)?
- mmap 错误:分段错误/指针无效错误
- C++ Winsock2 错误指针断点触发
- C++ 代码中的错误指针错误
- 数组错误指针上的增量运算符
- MAKEINTRESOURCE 返回资源 ID 的错误指针
- 分段错误C++指针
- 段错误指针
- C++ 错误 :: 指针数组的EXC_BAD_ACCESS
- 通过模糊 mat 从 std::vector: <int>cv::Exception 中获取错误指针
- 正在解决编译器错误:指针可能未初始化