You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承boost::noncopyable的类中默认移动构造函数为何无法编译?

继承boost::noncopyable类默认移动构造函数编译失败的原因分析

问题描述

当TestClass继承自boost::noncopyable时,若使用TestClass(TestClass&& other) = default;声明默认移动构造函数,会编译失败,报错提示该构造函数因默认定义非法被隐式删除;但手动实现移动构造函数则可正常编译,这一现象的原因是什么?

对应的测试代码如下:

#include <iostream>
#include <optional>
#include <boost/noncopyable.hpp>

class TestClass : public boost::noncopyable {
public:
    TestClass() {
        std::cout << "Constructed...\n";
    }

    TestClass(TestClass&& other) = default;

    //TestClass(TestClass&& other)  {
    //    std::cout << "Move constructor...\n";
    //}

    TestClass& operator=(TestClass&& other)  {
        std::cout << "Move assignment...\n";
        return *this;
    }
};

TestClass doThing() {
    std::optional<TestClass> tc = std::make_optional<TestClass>(TestClass{});
    return std::move(*tc);
}

int main() {
    const TestClass t = doThing();
}

原因分析

  1. boost::noncopyable的实现机制
    boost::noncopyable通过将自身的拷贝构造函数和拷贝赋值运算符声明为private且不提供实现,强制子类无法进行拷贝操作。它本身并没有显式定义移动构造函数或移动赋值运算符。

  2. 默认移动构造函数的生成规则
    当使用= default声明移动构造函数时,编译器会尝试生成一个默认的移动构造函数,这个函数会递归地对所有基类和成员变量执行移动操作。
    对于TestClass的基类boost::noncopyable,由于没有显式定义移动构造函数,编译器会尝试调用它的拷贝构造函数来完成"移动"(这是C++的 fallback 规则:当没有移动构造时,尝试用拷贝构造替代)。但boost::noncopyable的拷贝构造函数是private的,编译器无法访问,因此默认移动构造函数的生成会失败,最终被标记为隐式删除,导致编译报错。

  3. 手动实现移动构造函数的差异
    手动实现移动构造函数时,我们并没有显式处理基类boost::noncopyable的移动(因为它本身没有任何需要移动的成员变量或状态),编译器不会尝试去调用基类的拷贝或移动构造函数,因此可以绕过上述的访问权限问题,正常编译通过。

内容的提问来源于stack exchange,提问作者rmsantos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:20:21