我正在审查C++参考文献,我试图推断为什么下面这段代码符合:
#include <string>
class Foo {
public:
Foo(const std::string& label)
: d_label(label) {}
private:
std::string d_label;
};
int main(int argc, const char** argv) {
Foo("test");
return 0;
}
这里,我们将一个常量字符串的引用赋值给一个字符串。在这样做的时候,是否制作了一个非常数的label
副本?如果是这样的话,为什么我们可以复制一个const对象本身就是非常量呢?否则,在复制构造函数/赋值调用方面,这里到底发生了什么?
发布于 2017-01-05 08:53:08
在C++中,关键字const
实际上表示只读。要制作对象的副本,您不需要写访问权限。因此,您可以将const std::string
复制到std::string
中。
还要注意,在C++中复制意味着在默认情况下进行深度复制。这就是所谓的值语义。因此,操作复制的字符串不会对原始字符串做任何操作。
现在来看你的最后一个问题:下面这行是怎么回事?
测试Foo(“
”);
"test"
的类型为const char[5]
。编译器搜索匹配的Foo
构造函数。由于"test"
可以隐式转换为std::string
,因此
basic_string<CharT,Alloc>::basic_string( const CharT * s, const Alloc & a = Alloc() );
构造函数时,将执行此转换,即从"test"
构造一个临时std::string
。然后将对此临时函数的常量引用传递给构造函数
Foo::Foo( const std::string & label );
此构造函数依次调用std::string
的复制构造函数,以构造Foo
的d_label
成员
basic_string<CharT,Alloc>::basic_string( const basic_string & other );
发布于 2017-01-05 07:47:48
这里没有发生任何任务。d_label(label)
用label
初始化变量d_label
,随后调用string
类型的。
让我们仔细看看:
Foo("test");
使用其类型为const char[5]
const std::string& label
初始化"test"
,字符串引用(label
)正被初始化为具有const char[5]
类型的值。此初始化是有效的,因为可以将通过decaying到const char *
的"test"
传递给其中一个获得const char *
.string
构造函数。label
是对存储label
.Foo::d_label
使用string
引用的对象初始化string
类型的点复制构造函数,并构造发布于 2017-01-05 08:07:38
C++同时提供了引用语义和值语义:对象具有值,然后您可以引用对象。
std::string d_label
d_label
是一个包含字符串值的对象。它被认为拥有将字符串作为内存资源保存的字节。这种所有权概念使使用d_label
作为修改字符串的接口变得更加合理。
常量标准::字符串和标签
label
是对字符串的只读引用。这与“对const
字符串的引用”并不完全相同。它引用的对象可能不是(也可能不是) const
。
标签:d_label(
)
这将使用复制构造函数使用label
的内容初始化d_label
。然后,您可以随心所欲地处理副本。您知道,复制过程不会修改label
的底层对象,因为label
被声明为const &
。
https://stackoverflow.com/questions/41479663
复制相似问题