c++ static_cast and references
c++ static_cast and references
struct A{};
struct B : A{};
int main()
{
A a;
A& a_ref = a;
static_cast<B>(a); // *1
static_cast<B&>(a_ref); // *2
return 0;
}
(*1)产生错误,我理解原因。(*2) 编译正常,但为什么呢?而且,只要它编译并假设B
包含一些属性,如果我将a_ref
转换为B&
然后尝试访问这些属性怎么办?我想我会遇到运行时错误或其他错误。
因此,正如我所看到的,有一种情况会导致崩溃,并且没有办法避免它,这与dynamic_cast
不同,在中可以检查 null 转换结果或将代码放在try-catch
区域中。我必须如何处理需要投射引用并确保我真的得到正确的引用的情况。
来自标准 n3337 草案 5.2.9/2
类型为"cv1 B"的左值,其中 B 是类类型,可以转换为类型"对 cv2 D 的引用",其中 D 是类从 B 派生(条款 10),如果存在从"指向 D"到"指向 B 的指针"的有效标准转换 (4.10),cv2 与 cv1 具有相同的 CV 资格,或比 CV1 更高的 CV 资格,而 B 既不是虚拟基类的 D 也不是 D 的虚拟基类的基类。
在您的情况下:
B
是从 A
派生的类,两者都是非常量,并且允许从 A*
转换为 B*
,A
不是 D
的虚基类。
static_cast<>
只会检查类型是否兼容
在 1 类型不直接兼容的情况下,因为 re 不是描述 A 和 B 之间复制关系的运算符
在情况 2 中,强制转换是引用强制转换,就编译器而言A*
可以转换为B*
,因为它们是兼容的。编译器将不知道指针a_ref
包含什么,因此这就是它允许您使用它的原因。 dynamic_cast<>
还会检查指针指向的类。
boost::polymorphic_downcast
(doc) 的原因之一 - 在调试中它使用 dynamic_cast
后跟断言,在发布中它是 static_cast
,所以没有性能影响。
(*2) 编译正常,但为什么呢?
通常,您不能静态检查动态类型;static_cast
不会执行任何动态类型检查。它允许根据静态类型可能有效的任何转换,包括根据动态类型无效的转换。
如果我将a_ref投射到 B& 然后尝试访问属性怎么办?
未定义的行为。如果您使用 static_cast
,那么您有责任确保转换有效。
我必须如何处理需要投射引用并确保我真的得到正确的引用的情况。
对于多态类型,请使用 dynamic_cast
。应用于引用,如果转换无效,它将抛出std::bad_cast
。
对于非多态类型,您只能靠自己。
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- BoostPython and CMake
- OpenSSL BIO and SSL_read
- Gurobi GRBModel and GRBmodel in C++
- std::visit and std::variant usage
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- Directx12 and keystrokes
- different between int **arr =new int [ n]; and int a[i][j]?
- C++ getenv and setenv
- Inference pytorch C++ with alexnet and cv::imread image
- 如何使用 std::sort with pair and references
- C++:关于"valid pointers and references"的澄清
- c++ static_cast and references
- 为什么这给了我"Undefined references to constructors and destructors"?
- 使用C++"How in list all iterators and references unaffected after any operation"的后端过程
- Rvalue references and std::forward