V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kerrspace
V2EX  ›  程序员

C++在什么情况下会把拷贝构造函数写成私有的?

  •  
  •   kerrspace · 2022-10-08 23:22:03 +08:00 · 1299 次点击
    这是一个创建于 559 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近我在看一个开源的腾讯的 json parser ,在同类 parser 里面据说速度第一( rapidjson ),它那个里面有个类叫 Document ,我在封装的时候写了这么一个函数

    rapidjson::Document JsonParser::getJsonDocument(std::string filename)
    {
    // open the JSON file
    std::ifstream jFile(filename);
    if(!jFile.is_open())
    throw JsonParserException("Unable to open file " + filename + ".");

    // read the file contents
    std::stringstream contents;
    contents << jFile.rdbuf();

    rapidjson::Document doc;
    doc.Parse(contents.str().c_str());
    return doc;
    }

    他在最后 return doc 那里给我报错(只能传引用或者指针)。我去头文件一看,Document 这个类的拷贝构造函数是私有的。上面还有一行注释写着 prohibit copying 。

    我就想咨询一下各位大佬(我实在是刚工作的萌新),在什么情况下你们会把拷贝构造函数放在私有里面?这样做是为了实现什么目的呢?
    8 条回复    2022-10-09 13:47:39 +08:00
    nightwitch
        1
    nightwitch  
       2022-10-08 23:27:12 +08:00 via Android
    语意上不适合拷贝的就会禁用 copy 。比如复制一个 socket 不会打开两个连接,复制一个 fd 也不会打开两次文件。或者拷贝代价很大的也可能会禁用,但是一般会提供移动构造以转移所有权,没有的话就只能用指针管理了
    wevsty
        2
    wevsty  
       2022-10-08 23:34:28 +08:00
    不适合提供拷贝的对象都可能会把拷贝构造函数写成私有(或者标记为删除)。

    一部分是语义上不应该复制的对象会删除拷贝构造,2L 说的很明确。
    还有一部分也可能是为了避免产生隐式的复制影响速度就干脆删除拷贝构造函数,这样产生隐式拷贝的时候编译会报错提醒。
    Noicdi
        3
    Noicdi  
       2022-10-08 23:36:02 +08:00 via iPhone
    类不适用拷贝构造会设置私有,不设置的话编译器会提供默认拷贝构造函数,现在应该更倾向于用 delete 向编译器明确拒绝拷贝构造函数
    secondwtq
        4
    secondwtq  
       2022-10-08 23:37:56 +08:00   ❤️ 1
    这是 C++11 之前的老套路,想要禁止用户拷贝类的实例就把 copy-ctor 扔 private 里面。
    C++11 有了 =delete ,就基本没人这么用了(当然还是可以达到“只让类自己的成员函数调用”的目的 ...)
    因为 C++11 基本早就普及了,楼主可能学的时候不知道这码事
    secondwtq
        5
    secondwtq  
       2022-10-08 23:39:41 +08:00
    哦对,这库应该也是支持 C++98 的,所以可能省了个事选择用兼容性好的方法
    ysc3839
        6
    ysc3839  
       2022-10-08 23:43:26 +08:00 via Android
    防止意外拷贝消耗性能,要不然 move ,要不然显式拷贝。
    dangyuluo
        7
    dangyuluo  
       2022-10-09 05:48:22 +08:00
    估计还是老代码,moden C++里面的做法应该是

    ```
    TYPE& operator=(const TYPE&) = delete;
    ```
    jones2000
        8
    jones2000  
       2022-10-09 13:47:39 +08:00
    单件
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   911 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 21:00 · PVG 05:00 · LAX 14:00 · JFK 17:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.