显式复制构造函数
Posted
技术标签:
【中文标题】显式复制构造函数【英文标题】:Explicit copy constructor 【发布时间】:2012-07-13 21:33:07 【问题描述】:我已经扩展了 std::string 以满足我必须将自定义函数构建写入名为 CustomString
的字符串类的需要我已经定义了构造函数:
class CustomString : public std::string
public:
explicit CustomString(void);
explicit CustomString(const std::string& str);
explicit CustomString(const CustomString& customString);
//assignment operator
CustomString& operator=(const CustomString& customString);
... ;
在第三个构造函数(拷贝构造函数)和赋值运算符中,其定义为:
CustomString::CustomString(const CustomString& customString):
std::string(static_cast<std::string>(customString))
CustomString& CustomString::operator=(const CustomString& customString)
this->assign(static_cast<std::string>(customString));
return *this;
首先,因为这是一个“显式”;意味着需要显式转换才能分配给另一个 CustomString 对象;它在抱怨这项任务。
CustomString s = CustomString("test");
我不确定在哪里明确需要强制转换。
如果复制构造函数不是显式的,代码可以正常工作,但我想知道并实现显式定义,而不是“猜测正确的转换”。
【问题讨论】:
【参考方案1】:显式拷贝构造函数意味着拷贝构造函数不会被隐式调用,这就是表达式中发生的事情:
CustomString s = CustomString("test");
这个表达式的字面意思是:使用带有const char*
的构造函数创建一个临时的CustomString
。隐式调用CustomString
的复制构造函数以从该临时复制到s
。
现在,如果代码是正确的(即,如果复制构造函数不明确),编译器将通过直接使用字符串文字构造 s
来避免创建临时文件并删除副本。但是编译器仍然必须检查构造是否可以完成并在那里失败。
您可以显式调用复制构造函数:
CustomString s( CustomString("test") );
但我建议您完全避免使用临时的,只需使用 const char*
创建 s
:
CustomString s( "test" );
无论如何编译器会做什么......
【讨论】:
哦,是的,我完全理解您的答案(这是正确的答案,我已将其标记为最佳答案),但我将如何实现CustomString s = customStringObjectOnStack;
?
@mkhan3189 当且仅当 copy-ctor 不明确时,您才能实现 CustomString s = customStringObjectOnStack。对于第二个问题,kDelimited 是 CustomString 还是其他?并且 + 你的函数是 const,所以 c.append(static_castc.append(static_cast<std::string>(*this))
适用于隐式 copy-ctor 声明。所以一切都很好。该线程可以关闭。
@mkhan3189:您可以通过 CustomString s = customStringObjectOnStack;
来实现 CustomString s = customStringObjectOnStack;
,而不是通过 =
语法隐式使用该复制构造函数,而是显式调用复制构造函数:CustomString s( customStringObjectOnStack );
【参考方案2】:
从 std::string 派生是不安全的,因为 std::string 没有虚拟析构函数。至于您的问题-您的复制构造函数不应该是明确的,以允许以下用法:
CustomString s = "test";
我也不知道你为什么要将复制构造函数声明为显式的,因为它不是必需的。 仅当您将 CustomString 对象声明为:
CustomString s(CustomString("test"));
【讨论】:
@ildjarn:为什么懒惰?它是正确的(不是最优的,但正确的)解决了问题并提供了解决方案...... @DavidRodríguez-dribeas 当 ildjarn 发表评论时,答案相当短。 谢谢,很好的答案,但这是懒惰的,因为我要求这样做来改进我编写代码的方式,而不是仅仅完成工作。无论如何谢谢:) 只要 OP only 使用CustomString
s 并且不尝试通过std::string
指针delete
和new CustomString
,就是真的这个推导有什么不安全的地方吗?
“只要[...],有什么不安全的吗?”。除非您有办法随着时间的推移可靠且一致地执行条件,包括同事的代码以及将来可能被复制粘贴到的任何地方,否则该问题的答案始终是肯定的。无论“[...]”中有什么。以上是关于显式复制构造函数的主要内容,如果未能解决你的问题,请参考以下文章