当使用指针初始化时,如果有多个构造函数接受指针参数,则nullptr可能不明确 .
您可以通过强制转换C cast或static_cast来解决此问题,例如:
#include <iostream>
#include <cstddef>
using namespace std;
struct A{
A(int*){ cout << "int constructor" << endl;}
A(double*) { cout << "double constructor" << endl;}
};
struct B{
B(std::nullptr_t) { cout << "nullptr constructor" << endl;}
B(int*){ cout << "int constructor" << endl;}
B(double*) { cout << "double constructor" << endl;}
};
int main(){
//A a(nullptr); constructor is ambiguous
A a1((int*)nullptr);// int constructor
A a2(static_cast<double*>(nullptr));// double constructor
B b(nullptr);// nullptr constructor
return 0;
}
我包含B来说明存在std :: nullptr_t的构造函数是可能的但是对于这个问题我们将重点放在A.
从“Why use static_cast(x) instead of (int)x?”我了解C cast最危险的事情是你不知道将使用哪个:
主要原因是经典C强制转换不区分我们称之为static_cast <>(),reinterpret_cast <>(),const_cast <>()和dynamic_cast <>() . 这四件事完全不同 .
这些演员阵容中的任何一个对于nullptr是不安全的还是你可以安全地使用C风格的演员阵容?
2 回答
无论你如何强迫编译器忽略它自己的一套(非常好的)规则并相信你(通常是错误的)直觉,
reinterpret
强制转换是不安全的 .我认为_1819742也有点危险,因为它允许你编译向下铸造和侧向铸造 . 有时当刚刚开始使用它时,这会导致出现令人困惑的NULL指针或运行时错误 .
在你的例子中它没有't matter since the conversion is trivial, so you 1819743 use anything, but you probably shouldn't . C风格的案例可能是静态的,因为它很重要(但你不能保证!) . [1819746_不保证!) . 这更像是一个安全的惯例 - 使用
static_cast
,因为它是保证它的方式 . 如果您的代码变得更加先进/复杂/困难,那么"be safe"规则可以真正帮助您避免讨厌的错误 .通常,
C++
应该不包含原生C
,至少作为初学者,可能大部分时间都是如此 .我觉得如果类允许构造多个指针类型,那么类作者应该对显式空指针负责 .
默认位置是不处理空指针,这是完全有效的 . 如果作者想要处理显式空指针,则可以添加nullptr_t或no-args构造函数,但如果不是,则用户应将其作为公司设计警告 .