Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++如何检测何时将NulLPTR传递到函数,其中期望STD::string?_C++_String_Nullptr - Fatal编程技术网

C++如何检测何时将NulLPTR传递到函数,其中期望STD::string?

C++如何检测何时将NulLPTR传递到函数,其中期望STD::string?,c++,string,nullptr,C++,String,Nullptr,我找不到对此给出明确答案的线索- 我有一个构造函数,例如: FanBookPost::FanBookPost(Fan* owner, std::string content); Fan是我代码中的另一个类,但内容是有问题的: 因为std::string不是指针,所以我希望用fan调用构造函数,nullptr是不可能的。然而,它编译。。。并在运行时因EXC\u访问错误而崩溃 这是可以避免的吗 这里的问题是,当调用std::string的构造函数时会发生崩溃,因为在那里访问了解释为const ch

我找不到对此给出明确答案的线索-

我有一个构造函数,例如:

FanBookPost::FanBookPost(Fan* owner, std::string content);
Fan是我代码中的另一个类,但内容是有问题的:

因为std::string不是指针,所以我希望用fan调用构造函数,nullptr是不可能的。然而,它编译。。。并在运行时因EXC\u访问错误而崩溃


这是可以避免的吗

这里的问题是,当调用std::string的构造函数时会发生崩溃,因为在那里访问了解释为const char*的nullptr。除了告诉其他人不要做狗屎,你在这里没有什么可以做的。这不是构造函数的问题,因此也不是你的责任,除此之外,你不能阻止它。

这里的问题是,当std::string的构造函数被调用为null ptr,并在那里被访问为const char*时,就会发生崩溃。除了告诉其他人不要做狗屎,你在这里没有什么可以做的。这不是构造函数的问题,因此也不是你的责任,除了你不能阻止它之外。

你观察到的是,在这种情况下,你可以从字符指针nullptr隐式创建一个std::string,然后传递给函数。但是,不允许从空指针创建字符串。方法签名没有问题,只是客户端使用违反了std::string构造函数的约定。

您观察到的是,在这种情况下,您可以从字符指针nullptr隐式创建std::string,然后将其传递给函数。但是,不允许从空指针创建字符串。方法签名没有问题,只是客户端使用违反了std::string构造函数的约定。

如果您真的想安全,那么使用代理/包装器类型如何:

template<typename T>
struct e_t
{
public:
    inline e_t ( e_t const & other )
        : m_value( other.m_value )
    {}

    inline T & value( void )                { return m_value; }
    inline operator T&()                    { return m_value;   }
    inline e_t( const T& c ) : m_value( c )     {}

private:
    T m_value;
};

void FanBookPost(int* owner, e_t<std::string> content) {
}

int main()
{
    int n = 0;
    //FanBookPost(&n, 0); // compiler error
    //FanBookPost(&n, nullptr); // compiler error
    //FanBookPost(&n, ""); // unfortunately compiler error too
    FanBookPost(&n, std::string(""));
}

如果您确实希望安全,那么使用代理/包装器类型如何:

template<typename T>
struct e_t
{
public:
    inline e_t ( e_t const & other )
        : m_value( other.m_value )
    {}

    inline T & value( void )                { return m_value; }
    inline operator T&()                    { return m_value;   }
    inline e_t( const T& c ) : m_value( c )     {}

private:
    T m_value;
};

void FanBookPost(int* owner, e_t<std::string> content) {
}

int main()
{
    int n = 0;
    //FanBookPost(&n, 0); // compiler error
    //FanBookPost(&n, nullptr); // compiler error
    //FanBookPost(&n, ""); // unfortunately compiler error too
    FanBookPost(&n, std::string(""));
}
问题是std::string有一个非显式的ctor,它将char*作为唯一必需的参数。这提供了从nullptr到std::string的隐式转换,但提供了未定义的行为,因为该构造函数特别需要非null指针

有几种方法可以防止这种情况。可能最有效的方法是对std::string进行非常量引用,这将需要传递一个非临时字符串作为参数

FanBookPost::FanBookPost(Fan* owner, std::string &content);
这确实会产生一个不幸的副作用,即赋予函数修改传递的字符串的能力。这还意味着,使用一致性编译器1,您将无法向函数传递null ptr或字符串文本,您必须传递std::string的实际实例

如果希望能够传递字符串文字,那么可以添加一个重载,该重载接受char const*参数,也可能接受nullptr_t参数。前者会在创建字符串并调用引用字符串的函数之前检查非空指针,而后者会记录错误并无条件终止程序,或者(可能)记录错误并引发异常

这既烦人又不方便,但可能比目前的情况要好

不幸的是,上次我注意到MS VC++在这方面不符合要求。它允许通过非常量引用传递临时对象。通常这是相当无害的,它只是让你修改临时的,但通常没有明显的副作用。但在这种情况下,它要麻烦得多,因为您特别依赖它来防止传递临时对象。 问题是std::string有一个非显式的ctor,它将char*作为唯一必需的参数。这提供了从nullptr到std::string的隐式转换,但提供了未定义的行为,因为该构造函数特别需要非null指针

有几种方法可以防止这种情况。可能最有效的方法是对std::string进行非常量引用,这将需要传递一个非临时字符串作为参数

FanBookPost::FanBookPost(Fan* owner, std::string &content);
这确实会产生一个不幸的副作用,即赋予函数修改传递的字符串的能力。这还意味着,使用一致性编译器1,您将无法向函数传递null ptr或字符串文本,您必须传递std::string的实际实例

如果希望能够传递字符串文字,那么可以添加一个重载,该重载接受char const*参数,也可能接受nullptr_t参数。前者会在创建字符串并调用引用字符串的函数之前检查非空指针,而后者会记录错误并无条件终止程序,或者(可能)记录错误并引发异常

这既烦人又不方便,但可能是 优于目前的情况

不幸的是,上次我注意到MS VC++在这方面不符合要求。它允许通过非常量引用传递临时对象。通常这是相当无害的,它只是让你修改临时的,但通常没有明显的副作用。但在这种情况下,它要麻烦得多,因为您特别依赖它来防止传递临时对象。
如果确实需要,可以使用const char*版本重载它,该版本在不为null的情况下转发。调用std::string构造函数时会发生崩溃,这不是代码的问题。可以使用接受std::nullptr\t的函数重载它。非空指针常量不会选择此重载。@dyp,但这不会阻止诸如char*c=0;FanBookPost fbp…,c;甚至FanBookPost fbp…,0@delnan 0是一个空指针常量。如果确实需要,可以使用const char*版本重载它,该版本在不为空时转发。调用std::string构造函数时会发生崩溃,这不是代码的问题。可以使用接受std::nullptr\t的函数重载它。非空指针常量不会选择此重载。@dyp,但这不会阻止诸如char*c=0;FanBookPost fbp…,c;甚至FanBookPost fbp…,0@delnan 0是空指针常量。我建议使用禁用语言扩展。我建议使用禁用语言扩展。