【问题标题】:C++ - Move constructor of class with a fixed size, c-style array memberC++ - 移动具有固定大小、c 样式数组成员的类的构造函数
【发布时间】:2018-09-05 14:26:48
【问题描述】:

我有一个具有固定大小的 c 样式数组成员的类,例如 this:

struct some {
    static const size_t name_length = 64;

    char name[name_length+1];

    some() = default;

    some(const some& s) {
        memcpy(name, s.name, strlen(s.name)+1);
    }

    // other constructors...

    void set_name(const char* s) {
        auto len = strlen(s);
        if (len > name_length) {
            len = name_length;
        }
        memcpy(name, s, len);
        name[len] = '\0';
    }
};

复制构造函数工作正常,但我将如何实现移动构造函数?

我知道我可以用 std::array 替换 c 样式的数组,但是如果没有它,还有什么办法吗?

PS:很多人建议我使用编译器生成的复制/移动构造函数……不幸的是,在真正的类中,我不能这样做,因为这个类有其他成员和其他构造函数……我只是想知道是否有办法移动固定大小的成员。我猜没有,移动构造函数将不得不复制字节。我想知道这是否是std::array 所做的......

【问题讨论】:

  • 你会通过不实现一个来实现一个。使用std::stringstd::array 并让编译器来做。
  • 您的移动构造函数将与您的复制构造函数相同。没有聪明的方法可以“移动”一个固定大小的数组。但是您为什么不想使用std::array?对我来说这似乎是个好主意。
  • 这堂课没有什么可动的。你不需要它。
  • 有什么理由不使用std::string 和零规则?
  • 这并没有解决问题,但如果目标是让类保存一个以 nul 结尾的 C 字符串,set_name 中的代码是错误的。如果s 指向的字符串长于缓冲区大小,则对memcpy 的调用会将字符从s 复制到缓冲区中,直到达到限制。结果将是 name 中的文本不是以 nul 结尾的。

标签: c++ constructor c++17 move-constructor


【解决方案1】:

由于您的班级没有直接拥有任何资源(也没有通过成员间接拥有),因此不要浪费时间编写 move-ctor 和/或 move-assignment,没有任何优势:
无论如何,它们必须与复制变体一样。

另外,编写自己的自定义 copy-ctor 是浪费时间,因为默认的完全没问题,并且具有使类变得不平凡的缺点。不过,如果您必须进行演示,请在课堂上明确默认它以保持琐碎性。

顺便说一句,请考虑您是否需要 0 终止,或者可以使用最大长度的 0 填充序列。仅比 2 的幂次方多 1 是相当尴尬的大小。

【讨论】:

    【解决方案2】:

    如何实现移动构造函数?

    这个类没有资源,没有指针成员,所以它的移动构造函数和它的复制构造函数是一样的。

    此外,您不需要在此处手动定义复制构造函数,编译器生成的构造函数会做正确的事情 - 成员方式复制:

    some(const some& s) = default;
    

    或者,您可以删除这两个构造函数。这也将允许您使用聚合初始化器语法来初始化您的类,例如:some s = {"it is something"};

    【讨论】:

    • 指针与否与此无关,虽然有相关性。
    • @Deduplicator 这句话太强了以至于不正确。在这种特定情况下,您的陈述显然是不正确的。
    • “这个类没有资源”可能是更好的措辞
    • @Caleth 我接受那条线。
    猜你喜欢
    • 2021-12-23
    • 2015-05-25
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    相关资源
    最近更新 更多