一个类中的字符数组初始化

时间:2017-05-25 18:59:49

标签: c++ gcc c++14

我正在关注一个问题,其中一个答案包含以下代码段:

    private:
      char *m_data;

     public:
      HelloWorld() {
        m_data = new char[14]{"Hello, World!"};   // should work in c++14
                                          // ^ the error points here

}

根据作者应该在c ++ 14中工作,但是当我尝试编译时,我收到以下错误:

"invalid conversion from 'const char*' to 'char'

问题在哪里以及如何解决?

4 个答案:

答案 0 :(得分:2)

该代码至少根据C ++ 2017标准(以及编写错误报告的C ++ 2014标准)有效。似乎使用的编译器不支持此功能。如果是,则将字符串文字复制到分配的内存

#include <cstring>

//...
// m_data = new char[14]{"Hello, World!"};   
m_data = new char[14];
std::strcpy( m_data, "Hello, World!" );   

答案 1 :(得分:2)

原始代码应该有效。 C ++ 14 [expr.new] /7.4甚至明确地提到了这个确切的情况,说如果字符串文字对于数组来说太长则是错误的:

  

noptr-new-declarator 中的表达式在以下情况下是错误的:[...]

     
      
  • new-initializer braced-init-list 以及为其提供初始值设定项的数组元素数量(包括终止{{1}在字符串文字中)超过了元素的数量   初始化。
  •   

在最新的标准草案中,[dcl.init.list] / 3中列表初始化的定义说:

  

否则,如果'\0'是一个字符数组,并且初始化列表的单个元素是一个适当类型的字符串文字,则按照该部分的描述执行初始化。

(并且在此情况下未触发“其他”之前的前一点)。

其他评论提到了一些关于初始化规则的混淆。请参阅DR 1490 - 可以阅读C ++ 11文本说T格式错误,因为它试图将字符串文字作为char s[4]{"abc"};的初始化程序。然而,意图是这个代码工作 - 任何措辞暗示否则将是有缺陷的措辞。

这被认为是一个缺陷,但解决过程(DR 1467)直到C ++ 14发布后才完成。

缺陷解决方案被认为是追溯性地取代他们解决的文本;所以符合C ++ 14的代码应该使用我在上面引用的规则,这是明确无误的。常识也会对C ++ 11的一致性使用相同的规则。

答案 2 :(得分:1)

教程错了。您需要输入一个文字字符数组初始值设定项,如下所示:

m_data = new char[14]{'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0'};

请记住,您必须手动在最后添加 null终止符 '\0'

答案 3 :(得分:-3)

问题是你的教程指向了错误的方向;如某些评论所示,修复方法是使用std::string

private:
  std::string m_data;

 public:
  HelloWorld() {
    m_data = "Hello, World!";
  }  

在C ++中,使用std::string代替char*并避免new都是首选;你应该避免写“C风格”的C ++,C是一种不同的语言。

使用std::string还可以让您不必将析构函数(未显示)写入delete[] m_data。它还使复制/赋值的默认实现工作,而char*则不然。使用std::string有很多充分的理由。