您的位置:首页 > 编程语言 > C语言/C++

C++13.1 复制构造函数-----临时对象(不是很懂)

2015-06-24 15:04 423 查看

简介

对于引用、指针以及临时变量–http://blog.sina.com.cn/s/blog_673ef8130100imsp.html

当用类类型对象时(类类型的引用)进行初始化时,初始化的复制形式和直接形式就有所不同了:直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。

复制初始化首先使用指定构造函数创建一个临时对象(7.3.2),然后用复制构造函数将那个临时对象复制到正在创建的对象:

===============================================================================================

只有单个形参,而且该形参是对本类类型对象的引用(const修饰),这样的构造函数称为复制构造函数。与默认构造函数一样,复制构造函数可由编译器隐式调用。复制构造函数可用于:

根据另一个同类型的对象显示或隐式初始化一个对象;

复制一个对象,将它作为实参传给一个函数;

从函数返回时复制一个对象;

初始化顺序容器中的元素;

根据元素初始化式列表初始化数组元素。

一、复制构造函数—只有单个形参,而且该形参是对本类类型对象的引用(const修饰)

1、对象的定义形式

c++支持两种初始化形式:直接初始化和复制初始化,复制初始化使用=符号,而直接初始化将初始化放在圆括号中。(2.3.3节)

注意:初始化不是赋值,初始化指创建变量并给它赋初值,而赋值则是擦除对象当前值并用新值代替。

//一般类型的变量初始化
int ival(1024);
int ival=1024;
//我们本章则把类型换成了类类型


当用类类型对象时(类类型的引用)进行初始化时,初始化的复制形式和直接形式就有所不同了:直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。

复制初始化首先使用指定构造函数创建一个临时对象(7.3.2),然后用复制构造函数将那个临时对象复制到正在创建的对象:

解释一下 7.3.2节的临时对象

函数的返回值用于初始化在调用函数处创建的临时对象。在求解表达式时,如果需要一地方存储其运算结果,编译器会创建一个没有命名的对象,这就是临时对象。

用函数返回值初始化临时对象与用实参初始化形参的方法是一样的。如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象,当函数返回非引用类型时,其返回值既可以是局部对象,也可以是求解表达式的结果。(具体看7.3.2节)

string make_plural(size_t ctr,const string &word,const string &ending){
  return (ctr==1)?word:word+endin;//函数返回值是非引用类型,所以既可以返回局部对象,也可以是求解的表达式
  //函数要么返回形参word的副本,要么返回一个未命名的临时string对象,这个string对象是由字符串word和ending相加产生的。
}


当函数返回引用类型时,没有复制返回值,相反,返回的是对象本身。调用函数和返回结果时,都没有复制这些string对象。

千万不要返回局部对象的引用

string null_book = "9-999-9999-9";//复制初始化
string dots(10,'.');//直接初始化
string empty_copy = string();//复制初始化
string empty_direct;//直接初始化


与普通类型相比,对于类类型对象,只有指定单个实参或显示创建一个临时对象用于复制时,才使用复制初始化。

创建dots时,调用参数为一个数量和一个字符的string构造函数并直接初始化dots的成员。创建null_book时,编译器首先调用接受一个C风格字符串形参的string构造函数,创建一个临时对象,然后,编译器使用string复制构造函数将null _book初始化为那个临时对象的副本。

empty_copy和empty_direct的初始化都调用默认构造函数。对前者初始化时,默认构造函数创建一个临时对象,然后复制构造函数用该对象初始化empty_copy。对后者初始化时,直接运行empty_direct的默认构造函数。

直接初始化和复制初始化仅在低级别优化上存在差异。然而,对于不支持复制的类型,或者使用非explicit的构造函数(12.4.4)的时候,他们的本质区别:

ifstream file1("filename");//直接初始化
ifstream file2="filename";//错误!!!复制构造函数是私有的。IO类型的对象不能复制(8.1),所以不能对那些类型的对象使用复制初始化。
//只有当Sale_item(const string&)构造函数不是explicit
Sale_item item = string("9-999-99999-9");


2、形参和返回值———非引用的类类型

当形参为非引用类型(7.2.1)的时候,将复制实参的值,有一个临时变量。类似的,以非引用类型作返回值时,将返回return语句中的值的副本(7.3.2)。

当形参或返回值为非引用的类类型时,也将返回return语句中值得副本,只是它是由复制构造函数进行复制。

string make_plural(size_t,const string&,const string&);
//这个函数隐式使用string复制构造函数返回给定单词的复数形式。形参是const引用,不能复制。


3、初始化容器元素

复制构造函数可用于初始化顺序容器中的元素。

vector<string> svec(5);//编译器首先使用string默认构造函数创建一个临时值来初始化svec,然后使用复制构造函数将临时值复制到svec的每个元素。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: