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

2022-10-08 23:22:03 +08:00
 kerrspace
最近我在看一个开源的腾讯的 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 。

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

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

```
TYPE& operator=(const TYPE&) = delete;
```
jones2000
2022-10-09 13:47:39 +08:00
单件

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/885397

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX