在c++中,防止整数0隐式转换为指针的最佳方法是什么?
What is the best way to prevent implicit conversion of integer 0 to pointer in c++
我试图找出最好的方法来防止整数0被隐式转换为nullptr_t,然后传递给接受指针的构造函数。显式不能做到这一点,但我可以让nullptr_t导致一个模棱两可的重载错误:
#include <typeinfo.h>
struct A {
explicit A(char*) { }
};
struct B {
B(nullptr_t a) = delete;
B(char*) { }
};
int main(int argc, char* argv[])
{
A a(0); // darnit I compiled...
B b1(0); // good, fails, but with only b/c ambiguous
B b2((char*)0); // good, succeeds
B b3(1); // good, fails, with correct error
}
还有比这更好的方法吗?另外,delete在这里究竟完成了什么?
删除A(int)
不会阻止A(char *)
被调用nullptr
。因此,您也需要删除A(nullptr_t)
。
即使这样也不能保护你免受这附近有一些无赖阶级可从0或nullptr
和隐式构造隐式转换为char *
。
#include <iostream>
struct A {
A(int) = delete;
A(std::nullptr_t) = delete;
explicit A(char * p) {
std::cout << "Constructed with p = " << (void *)p << std::endl;
}
};
struct X
{
X(long i) : _i(i) {}
operator char *() const { return (char *)_i; }
long _i;
};
int main()
{
X x(0);
A a(x);
return 0;
}
程序打印:
Constructed with p = 0
你可能认为这种可能性遥远到可以忽略;或者您可能更喜欢删除所有构造函数,一下子,他的论点不完全是一种类型这是你认可的。例如,假设批准的类型仅为char *
:
struct A {
template<typename T>
A(T) = delete;
explicit A(char * p) {}
};
struct X
{
X(long i) : _i(i) {}
operator char *() const { return (char *)_i; }
long _i;
};
int main()
{
// A a0(0);
//A a1(nullptr);
X x(0);
// A a2(x);
char *p = x;
A a3(p); // OK
return 0;
}
这里所有被注释掉的构造函数调用都无法编译。
如果您想阻止构造函数获取0
,一种选择是删除B(int)
:
B(int) = delete;
这显然比接受char *
的构造函数更适合B(0)
。
请注意,直到c++ 11, NULL
被指定为整数类型,即使在c++ 11及以后的版本中,它仍然可能被实现为#define NULL 0
。如果你这样做,B(NULL)
将不起作用。B(nullptr)
将工作,但仍然,我要警惕这是否值得做。
相关文章:
- 正在将指针转换为范围
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- C++:Lambda 函数指针转换的用例是什么?
- 如何将 int 指针转换为浮点指针
- 为什么在将 void 指针转换为整数指针时出现分段错误
- 将(N 个字节)无符号字符指针转换为浮点数和双 C++
- 我们可以在不知道其真实类型的情况下将基类指针转换为派生类指针吗?
- C++中数组大小未知的指针转换
- Antlr cpp 运行时 任何错误的指针转换?
- std::flush可以用于将对象指针转换为其封闭数组指针吗
- C 指针转换会导致内存访问冲突
- 模板类实例化中的指针转换无效
- 函数调用歧义(用户定义的转换和 Derived2Base 指针转换)
- 如何将 void(*)() 类型的指针转换为 void*
- 数组到指针转换期间的临时具体化
- 直接为浮点变量分配十六进制整数与通过指针转换分配之间的区别
- 将基类指针转换为派生的类指针
- 应对 std::字符串中的 std::<char>指针转换后的向量
- 在编译时将函数指针转换为 std::uintptr_t
- 将基类指针转换为未知派生类指针