在 C++ 中,类如何采用 const std::string&构造函数中的参数还要处理NULL?

发布于 2024-08-08 10:32:28 字数 748 浏览 2 评论 0原文

我正在尝试使用 std::string 参数创建一个类,但它也可以处理 NULL 而不引发异常。下面是代码示例:

class myString {
public:
    myString(const std::string& str) : _str(str) {}
    std::string _str;
};

int main() {
    myString mystr(NULL);
    printf("mystr = <%s>\n", mystr._str.c_str());
    return 0;
}

直观上,您会认为该程序应该打印“mystr = <>”并成功退出,但使用 g++ 时,它会给出此错误:

terminate called after throwing an instance of 'std::logic_error'  
what():  basic_string::_S_construct NULL not valid

How can I Change this class so that ittranslation NULL into ""而不是抛出logic_error异常?

(后记:正如您所怀疑的,“真正的”实现比这个示例更复杂一些,构造函数中有多个参数,并使用 _str 做更多有趣的事情——并正确地将其保持为私有。这个示例背后的动机是我们团队中的程序员倾向于在这种情况下使用 NULL 来实现历史目的,并且编译器不会捕获这一点。

I'm trying to work through ways to create a class with a std::string argument, but which also handles NULL without throwing an exception. Here's an example of the code:

class myString {
public:
    myString(const std::string& str) : _str(str) {}
    std::string _str;
};

int main() {
    myString mystr(NULL);
    printf("mystr = <%s>\n", mystr._str.c_str());
    return 0;
}

Intuitively, you'd think that this program should print "mystr = <>" and exit successfully, but instead with g++ it gives this error:

terminate called after throwing an instance of 'std::logic_error'  
what():  basic_string::_S_construct NULL not valid

How can I change this class so that it translates NULL into "" instead of throwing a logic_error exception?

(Postscript: As you'd suspect, the "real" implementation is a bit more complicated than this example, having several arguments in the constructor and doing more interesting things with _str -- and properly keeping it private. The motivation behind this example is that programmers in our team will tend to use NULL in this context for historical purposes, and the compiler won't catch this. Retraining everyone to always use "" is relatively hard. Alternatively, a clever solution would be easy)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

另类 2024-08-15 10:32:28

这里实际发生的情况是 NULL 被解释为 char const* 并尝试转换为 std::string (您可以将将 char* 类型的 C 字符串转换为 STL 字符串,对吧?)。

要处理它,您可以添加另一个构造函数

class myString {
public:
    myString(const std::string& str) : _str(str) {}
    myString(const char* str) : _str(str==NULL?"":std::string(str)) 
    { /* and do something special in the body */ }
    std::string _str;
};

但是如果您不需要什么特别的东西,更好的方法是

class myString {
public:
    myString(const std::string& str = "") : _str(str) {}
    std::string _str;
};
int main() {
    myString mystr;  //no () here!
    printf("mystr = <%s>\n", mystr._str.c_str());
    return 0;
}

What actually happens here is that NULL is interpreted as char const* and is being tried to be converted to std::string (you can convert C-strings of type char* into STL strings, right?).

To handle it, you may add another constructor

class myString {
public:
    myString(const std::string& str) : _str(str) {}
    myString(const char* str) : _str(str==NULL?"":std::string(str)) 
    { /* and do something special in the body */ }
    std::string _str;
};

But if you need nothing special there, the better way would be

class myString {
public:
    myString(const std::string& str = "") : _str(str) {}
    std::string _str;
};
int main() {
    myString mystr;  //no () here!
    printf("mystr = <%s>\n", mystr._str.c_str());
    return 0;
}
姐不稀罕 2024-08-15 10:32:28

真的,你不能。 NULL 不是字符串。但这里有一些替代方案:

  • 你可以重载你的构造函数
    省略字符串参数。

  • 您可以使用指针代替
    参考。

  • 您可以默认字符串参数
    到“”。

Really, you can't. NULL is not a string. But here are some alternatives:

  • You could overload your constructor
    to omit the string argument.

  • You could use a pointer instead of a
    reference.

  • You could default the string argument
    to "".

拥醉 2024-08-15 10:32:28

你不能。您需要有一些东西能够传递引用。您可以通过默认为空字符串(又名 "" 来解决此问题)。

或者,有另一个显式 ctor:

class myString {
 public:
   myString(const std::string& str) : _str(str) {}
   explicit myString(const char* str = NULL) : _str(str?str:"") {}
   std::string _str;
};

You cannot. You need to have something to be able to pass a reference to. You could though work around this by defaulting to null-strings aka "".

Alternatively, have another explicit ctor:

class myString {
 public:
   myString(const std::string& str) : _str(str) {}
   explicit myString(const char* str = NULL) : _str(str?str:"") {}
   std::string _str;
};
随遇而安 2024-08-15 10:32:28

您需要提供一个接受指针作为参数的构造函数。 NULL 是一个指针,而不是引用,因此正如您所看到的,如果您尝试将其视为字符串引用,将会导致灾难。

尝试:

class myString {
public:
    myString(const std::string& str) : _str(str) {}
    myString(const std::string* str) : { /* special-case logic here */}
    std::string _str;
};

You need to provide a constructor that accepts a pointer as an argument. NULL is a pointer, not a reference, and so as you've seen disaster will result if you try to treat it as a string reference.

Try:

class myString {
public:
    myString(const std::string& str) : _str(str) {}
    myString(const std::string* str) : { /* special-case logic here */}
    std::string _str;
};
围归者 2024-08-15 10:32:28

我假设这个问题并不像你的例子看起来那么简单。

您可以创建一个静态变量并为其赋值,而不是使用 NULL 参数。

class myString {
public:
    static std::string nullstring;
...
};

以及 .cpp 中的某处:

std::string myString::nullstring("");

并调用它:

int main() {
    myString mystr(myString::nullstring);
    printf("mystr = <%s>\n", mystr._str.c_str());
    return 0;
}

I'll assume this problem isn't as simple as your example appears to be.

Instead of using a NULL parameter, you can create a static variable and assign to that.

class myString {
public:
    static std::string nullstring;
...
};

and somewhere in a .cpp:

std::string myString::nullstring("");

And to call it:

int main() {
    myString mystr(myString::nullstring);
    printf("mystr = <%s>\n", mystr._str.c_str());
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文