当前位置:网站首页>Tips for this week 134: make_ Unique and private constructors
Tips for this week 134: make_ Unique and private constructors
2022-07-07 17:57:00 【-Flying crane-】
As totw#134 Originally published in 2017 year 5 month 10 Japan
By Google engineers Yitzhak Mandelbaum A literary creation
therefore , You read the tips #126 And prepare to leave something new . Everything is normal , Until you try to use absl::make_unique And use private constructors to construct objects , But the compilation failed . Let's take a look at a specific example of this problem , In order to understand what went wrong . then , We can discuss some solutions .
Example : Manufacturing widgets
You are defining a class to display widgets . Each widget has an identifier , These identifiers are subject to certain constraints . To ensure that these constraints are always met , You will be Widget The constructor of the class is declared private , And provide factory functions for users Make, Used to generate widgets with appropriate identifiers .( Suggestions on why factory functions are better than initialization methods , See Tips #42.)
class Widget {
public:
static std::unique_ptr<Widget> Make() {
return absl::make_unique<Widget>(GenerateId());
}
private:
Widget(int id) : id_(id) {
}
static int GenerateId();
int id_;
}
When you try to compile , You will get the following error :
error: calling a private constructor of class 'Widget'
{
return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
^
note: in instantiation of function template specialization
'absl::make_unique<Widget, int>' requested here
return absl::make_unique<Widget>(GenerateId());
^
note: declared private here
Widget(int id) : id_(id) {
}
When make When the private constructor has been accessed ,absl::make_unique Unable to work ! Be careful , This problem also appears under friends . for example :Widget Friends use absl::make_unique To construct Widget There will be the same problem .
Suggest
We recommend any of the following alternatives :
- Use new and absl::WrapUnique, But please explain your choice . for example :Widget Friends use absl
// Use new Access non constructor only return absl::WrapUnique(new Widget(...)); - Consider whether constructors can be safely exposed . If so , Then expose and record it when it is suitable for direct construction .
In many cases , Marking constructors private is overdesign . In these cases , The best solution is to mark your constructors public and record their correct use . However , If your constructor needs to be private ( for instance , To ensure class invariants ), Then use new and WrapUnique.
Why can't I friend absl::make_unique?
You may want to be friends absl::make_unique, So it can access your private constructor . It's a bad idea , There are several reasons :
First , Although a comprehensive discussion of friend practice is beyond the scope of this tip , But a good rule of thumb is “ Don't be a long-distance friend ”. otherwise , You will create a friend competition statement , A statement that is not maintained by the owner . See also style guide recommendations .
secondly , Please note that , You rely on absl::make_unique Implementation details , That is, it directly calls new. If it is refactored to call indirectly new—— for example , In the structure C++14 Or later ,absl::make_unique yes std::make_unique Another name for , And the friend declaration is invalid .
Last , Through friends absl::make_unique, You allow anyone to create objects in this way , So why not declare your constructor public , Then completely avoid this problem ?
std::shared_ptr Well ?
about std::shared_ptr, It's a little different . There is no absl::WrapSahred And simulation (std::shared_ptr(new T(…))) There are two distributions involved , among std::make_shared You can use one to complete . If this difference is important , Then consider idioms : Let the constructor take special tags that only specific code can create . for example :
class Widget {
class Token {
private:
Token() {
}
friend Widget;
};
public:
static std::shared_ptr<Widget> Make() {
return std::make_shared<Widget>(Token{
}, GenerateId());
}
Widget(Token, int id) : id_(id) {
}
private:
static int GenerateId();
int id_;
};
About idioms , Refer to the following article :
More Useful Empty Classes
Passkey Idiom and Better Friendship in C++
边栏推荐
- Mysql 索引命中级别分析
- 本周小贴士#141:注意隐式转换到bool
- Native JS verification code
- Create dialog style windows with popupwindow
- 本周小贴士#135:测试约定而不是实现
- Ansible learning summary (9) -- ansible loop, condition judgment, trigger, processing failure and other task control use summary
- MRS离线数据分析:通过Flink作业处理OBS数据
- 2021-06-28
- [OKR target management] case analysis
- 深度学习机器学习各种数据集汇总地址
猜你喜欢

Dragging the custom style of Baidu map to the right makes the global map longitude 0 unable to be displayed normally

Mui side navigation anchor positioning JS special effect

Robot engineering lifelong learning and work plan-2022-

使用popupwindow創建对话框风格的窗口
![Interviewer: why is the page too laggy and how to solve it? [test interview question sharing]](/img/0d/5d27c71a80e89b6bdea30672423004.png)
Interviewer: why is the page too laggy and how to solve it? [test interview question sharing]

Alertdialog create dialog

Mrs offline data analysis: process OBS data through Flink job

基于百度飞浆平台(EasyDL)设计的人脸识别考勤系统

Deep learning machine learning various data sets summary address

Face recognition attendance system based on Baidu flying plasma platform (easydl)
随机推荐
本周小贴士#140:常量:安全习语
ViewSwitcher的功能和用法
Ansible 学习总结(9)—— Ansible 循环、条件判断、触发器、处理失败等任务控制使用总结
如何在软件研发阶段落地安全实践
科学家首次观察到“电子漩涡” 有助于设计出更高效的电子产品
测试3个月,成功入职 “字节”,我的面试心得总结
How to implement safety practice in software development stage
Face recognition attendance system based on Baidu flying plasma platform (easydl)
深度学习机器学习各种数据集汇总地址
viewflipper的功能和用法
Main work of digital transformation
YARN Capacity Scheduler容量调度器(超详细解读)
Mrs offline data analysis: process OBS data through Flink job
Pro2: modify the color of div block
第3章业务功能开发(实现记住账号密码)
Introduction to OTA technology of Internet of things
Audio device strategy audio device output and input selection is based on 7.0 code
JS pull down the curtain JS special effect display layer
Automated testing: a practical skill that everyone wants to know about robot framework
什么是敏捷测试