首页 文章

使用nullptr初始化

提问于
浏览
0

当使用指针初始化时,如果有多个构造函数接受指针参数,则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 回答

  • 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 ,至少作为初学者,可能大部分时间都是如此 .

  • 0

    我觉得如果类允许构造多个指针类型,那么类作者应该对显式空指针负责 .

    默认位置是不处理空指针,这是完全有效的 . 如果作者想要处理显式空指针,则可以添加nullptr_t或no-args构造函数,但如果不是,则用户应将其作为公司设计警告 .

相关问题