C++primer里面的一个问题,求各位给个解答

andylfg 2014-03-31 04:00:45
C++primer第五版,P266里面的一个练习题7.51
问题:
vector将其单参数的构造函数定义成explicit的,而string则不是你觉得原因何在?
...全文
413 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
a35429708 2015-08-14
  • 打赏
  • 举报
回复
1楼的回答总结性很强,是很正确的
BX718 2014-07-20
  • 打赏
  • 举报
回复
因为vector接受一个容量参数的构造函数如果不是explicit的,那么就允许这样初始化:vector<int> ivec = 10; 意思就是初始化ivec为10个0,这样太让人迷惑了。所以定义成explicit比较好,不允许这样的写法。但是string s = "aaa"还是很好理解的。
zcdabing 2014-04-03
  • 打赏
  • 举报
回复
原因就是你这可以这么用string

#include<string>
string s="asd";
不然要初始化,就只能这样了

#include<string>
string s("asd");
第一个是个隐式转换,将一个字符转转换为string类,加上explicit压制隐式转换
andylfg 2014-04-03
  • 打赏
  • 举报
回复
引用 4 楼 zcdabing 的回复:
原因就是你这可以这么用string

#include<string>
string s="asd";
不然要初始化,就只能这样了

#include<string>
string s("asd");
第一个是个隐式转换,将一个字符转转换为string类,加上explicit压制隐式转换
谢谢4楼的回答,这么回答我就明白啦 哈哈哈 实际有用!
andylfg 2014-04-03
  • 打赏
  • 举报
回复
引用 3 楼 hywxn 的回复:
你也在看啊,好厚一本,都不知道看到什么时候
对啊,也在看呢,已经好几天没坚持了 诶 一定要坚持下来
hywxn 2014-04-02
  • 打赏
  • 举报
回复
你也在看啊,好厚一本,都不知道看到什么时候
andylfg 2014-04-02
  • 打赏
  • 举报
回复
额,说了这么多我也没搞懂啊···只能先放下了
shiguojie19892 2014-03-31
  • 打赏
  • 举报
回复
只有单个形参,而且该形参是对本类类型对象的引用(常用 const 修饰),这样的构造函数称为复制构造函数。 根据另一个同类型的对象显式或隐式初始化一个对象都会使用到复制构造函数: 复制一个对象,将它作为实参传给一个函数。 从函数返回时复制一个对象。 初始化顺序容器中的元素。 根据元素初始化式列表初始化数组元素。 (1)对象的初始化形式 C++ 支持两种初始化形式:直接初始化和复制初始化。复制初始化使用 = 符号,而直接初始化将初始化式放在圆括号中。 而当用于类类型对象时:直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。复制初始化首先使用指定构造函数创建一个临时对象,然后用复制构造函数将那个临时对象复制到正在创建的对象。 string null_book = "9-999-99999-9"; // copy-initialization string dots(10, '.'); // direct-initialization string empty_copy = string(); // copy-initialization string empty_direct; // direct-initialization 创建 null_book 时,编译器首先调用接受一个 C串形参的构造函数,创建临时对象,然后,编译器使用复制构造函数将null_book 初始化为那个临时对象的副本。 通常直接初始化和复制初始化仅在低级别上存在差异。然而,对于不支持复制的类型,或者使用非 explicit 构造函数(阻止构造函数隐式调用)之时,它们有较大区别: ifstream file1("filename"); // ok: direct initialization ifstream file2 = "filename"; // error: copy constructor is private // This initialization is okay only if // the Sales_item(const string&) constructor is not explicit Sales_item item = string("9-999-99999-9"); item 的初始化是否正确,取决于正在使用哪个版本的 Sales_item 类。某些版本将参数为一个 string 的构造函数定义为explicit的,则初始化失败;如果不是explicit的,则初始化成功。 (2)形参与返回值 当形参为非引用类型的时候,将复制实参的值;以非引用类型作返回值时,将返回 return 语句 中的值的副本。当形参或返回值为类类型时,由复制构造函数进行复制。 string make_plural(size_t, const string&, const string&); 这个函数隐式使用string 复制构造函数返回给定单词的复数形式。形参是const 引用,不能复制。 (3)初始化容器元素 复制构造函数可用于初始化顺序容器中的元素。例如,可以用表示容量的单个形参来初始化容器。容器的这种构造方式使用默认构造函数和复制构造函数: // default string constructor and five string copy constructors invoked vector<string> svec(5); 编译器首先使用 string 默认构造函数创建一个临时值,然后使用复制构造函数将临时值复制到 svec 的每个元素来初始化svec。但注意:分配一个空容器并将已知元素的值加入容器更有效。 (4)构造函数与数组元素 如果没有为类类型数组提供元素初始化式,则将用默认构造函数初始化每个元素。然而,如果有显式元素初始化式(如的花括号括住的数组初始化列表),则使用复制初始化来初始化每个元素。根据指定值创建适当类型的元素,然后用复制构造函数将该值复制到相应元素: Sales_item primer_eds[] = { string("0-201-16487-6"), string("0-201-54848-8"), string("0-201-82470-1"), Sales_item() }; 一、合成的复制构造函数 如果没有定义复制构造函数,编译器会自动合成一个。与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数。合成复制构造函数会对成员逐个进行初始化,将新对象初始化为原对象的副本。 编译器将原对象的每个非 static 成员,依次复制到正创建的对象。合成复制构造函数直接复制内置类型成员的值,类类型成员使用该类的复制构造函数进行复制。数组成员的复制要注意:虽然一般不能复制数组,但如果一个类具有数组成员,则合成复制构造函数将复制数组。复制数组时合成复制构造函数将复制数组的每一个元素。 class Sales_item { // other members and constructors as before private: std::string isbn; int units_sold; double revenue; }; // 合成复制构造函数如下所示: Sales_item::Sales_item(const Sales_item &orig): isbn(orig.isbn), // uses string copy constructor units_sold(orig.units_sold), // copies orig.units_sold revenue(orig.revenue) // copy orig.revenue { } // empty body 二、自定义的复制构造函数 class Foo { public: Foo(); // default constructor Foo(const Foo&); // copy constructor // ... }; 虽然也可以定义接受非 const 引用的复制构造函数,但形参通常是一个 const 引用。合成复制构造函数只完成必要的工作。只包含类类型成员或内置类型(但不是指针类型)成员的类,无须显式地定义复制构造函数,也可以复制。然而,有些类必须对复制对象时发生的事情加以控制: 有一个数据成员是指针,或者有成员表示在构造函数中分配的其他资源。 类在创建新对象时必须做一些特定工作。 这两种情况下,都必须定义复制构造函数。 三、禁止复制 有些类需要完全禁止复制。例如,iostream 类就不允许复制。但并不是不定义复制构造函数就能达到这个目的,因为即使我们不定义,编译器也会帮我们定义一个。为了防止复制,类必须显式声明其复制构造函数为private。当然,类的友元和成员还是可以进行复制的。如果想要连友元和成员中的复制也禁止,就可以声明一个(private)复制构造函数但不对其定义。

65,209

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧