C ++对象构造方法之间的区别 [英] Difference between C++ object construction methods

查看:56
本文介绍了C ++对象构造方法之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++中不同的构造语法总是让我有些困惑。在另一个问题中,建议尝试初始化像这样的字符串

  std :: string foo {'\0'}; 

这有效并产生预期的结果:长度为1的字符串,仅包含空字符。在测试代​​码时,我不小心输入了

  std :: string foo('\0'); 

这可以很好地编译(即使使用 -Wall ),但在运行时终止,

 终止是在抛出'std :: logic_error'
实例后调用的what():basic_string :: _ M_construct null无效
中止(转储)

现在,据我所知,没有<$的构造函数 c $ c> std :: string ,它使用单个字符作为参数,当我尝试间接传递字符时,这一假设得到了进一步的证实。

  char b ='\0'; 
std :: string a(b);

这会产生一个很长的编译错误。

  std :: string a(’z’)也是如此; 

所以我的问题是:什么允许 std :: string a('\ \0'); 进行编译,它与 std :: string a {'\0'}; 有何不同?




脚注:在Ubuntu上使用 g ++ 进行编译。这不会给我一个编译器错误,但以防万一...

解决方案

字符'\0'可隐式转换为 0 的整数值,从而表示实现定义的空指针常量。这:

  std :: string foo(’\0’); 

调用构造函数重载,接受类型为 const char * 作为参数,并导致未定义的行为。
等效于传递 0 NULL

  std :: string foo(0); // UB 
std :: string bar(NULL); // UB

引用表示第四和第五个构造函数重载状态:


如果s ...的行为是不确定的...包括s是
指针
的情况。


第二条语句:

  std :: string foo {'\0'}; // OK 

调用接受 std :: initializer_list< char> 作为参数,不会导致UB。



您可以调用构造函数重载,接受 count char s号:

  std :: string s(1,'\0'); 


The different construction syntaxes in C++ have always confused me a bit. In another question, it was suggested to try initializing a string like so

std::string foo{ '\0' };

This works and produces the intended result: a string of length 1 containing only the null character. In testing the code, I accidentally typed

std::string foo('\0');

This compiles fine (no warnings even with -Wall), but terminates at runtime with

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid
Aborted (core dumped)

Now, as far as I can tell, there is no constructor for std::string which takes a single character as an argument, and this hypothesis is further confirmed when I attempt to pass the character indirectly.

char b = '\0';
std::string a(b);

This produces a nice, lengthy compile error. As does this

std::string a('z');

So my question is: what allows std::string a('\0'); to compile, and what makes it different from std::string a{ '\0' };?


Footnote: Compiling using g++ on Ubuntu. This doesn't strike me as a compiler bug, but just in case...

解决方案

Character '\0' is implicitly convertible to integer value of 0 thus representing implementation-defined null pointer constant. This:

std::string foo('\0');

calls a constructor overload accepting pointer of type const char* as a parameter and results in undefined behavior. It is equivalent to passing 0 or NULL:

std::string foo(0); // UB
std::string bar(NULL); // UB

The reference for the 4th and 5th constructor overloads states:

The behavior is undefined if s... including the case when s is a null pointer.

The second statement:

std::string foo{'\0'}; // OK

calls a constructor accepting std::initializer_list<char> as a parameter and does not cause UB.

You could call the constructor overload accepting count number of chars instead:

std::string s(1, '\0');

这篇关于C ++对象构造方法之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆