如何将cstring复制到构造函数初始化列表中的成员变量

How to copy a cstring to a member variable in a constructors initializer list?

本文关键字:列表 成员 变量 初始化 构造函数 cstring 复制      更新时间:2023-10-16

不这样做:

myClass::myClass(char* name) :
    name(nullptr)
{
this->name = new char[strlen(name) + 1];
    strcpy(this->name, name);
}

如何在初始化列表中完全初始化name ?

既然我们在处理徒劳无功的练习:

myClass::myClass(char* name): name_{
  [](char* n) {
    auto ret = new char[strlen(n) + 1]; 
    strcpy(ret, n);
    return ret;
  }(name)
} {}

您可能会感兴趣。我想知道联合攻击战斗机(JSF)空中飞行器c++编码标准文档对此有何解释,所以我检查了:

(UNCLASS)

AV规则74:

非静态类成员的初始化将通过的成员初始化列表而不是通过赋值构造函数体。参见Meyers[6],第12项。

例外:

赋值应该在初始值不能用。表示时使用简单表达式(例如初始化数组值),或者当名称必须时在初始化之前被引入(例如,通过一个输入流)。

详情见附录A的AV规则74。"

(/UNCLASS)

现在,JSF规范是它那个时代的产物——大约在2005年,对于我所看到的版本来说——但是在新的c++语言变体出现之前,这是对这个问题的最佳思考。(例如,Meyers引用的是"Effective c++")

虽然新的语言标准提供了更多的选择,但当你问那些真正了解这些规范的人如何应用于非"std::*"时,让他们听你说话可能有点令人恼火。类型,通常你谈论的是c风格的,以空结尾的字符串。他们的反应往往是"不要那样做"。

不幸的是,在嵌入式系统世界和许多其他地方,std::array, std::string等,在任何数量的供应商特定的工具链中仍然遭受严重到严重的性能问题,偶尔别无选择,只能尝试找到一个折衷方案,在旧的C数据类型上使用现代c++最佳实践,这是到2022年绝对仍然会发生的事情。

对于我自己的C-string用例,我通常使用初始化列表将整个目标数组归零,然后在函数体中使用strncpy(注意N!)。这是因为我经常需要额外的麻烦来确保我正在使用的所有内存都被彻底清除了。

(我还会提到,如果你真的要确保这一点,有替代内存管理库是真正的偏执,但你可能会付出相当大的性能损失,所以最好先学习如何从你的代码中得到你想要的东西。但是,它们有时可以是一个不错的解决方案,可以帮助您支持没有时间进行改造的旧代码库。