c++之拷贝构造函数调用时机
test1:
#include<iostream>
using namespace std;
class Copy_construction {
public:
Copy_construction(int a = )
{
this->a = a;
cout << "这是有默认参数的构造函数!\n";
}
Copy_construction(const Copy_construction &obj)
{
cout << "这是拷贝构造函数!\n";
a = obj.a;
}
~Copy_construction()
{
cout << "一个对象被析构了!\n";
}
private:
int a;
};
void fuc(Copy_construction t)
{
cout << "fuc函数!\n";
}
void play_empty(void)
{
Copy_construction t1;//调用有默认实参的构造函数
Copy_construction t2 = t1;//调用拷贝构造函数
Copy_construction t3(t2);//调用拷贝构造函数
cout << "_________________\n";
fuc(t3);//实参初始化形参,调用拷贝构造函数
}
int main()
{
play_empty(); cout << "hello world!\n";
return ;
}
运行结果
test2:
修改fuc函数为引用或者指针类型。
void fuc(Copy_construction *t)
{
cout << "fuc函数!\n";
} void fuc(Copy_construction &t)
{
cout << "fuc函数!\n";
} /*****引用或者指针类型调用时不会调用拷贝构造函数****/
test3:
匿名对象的出现:
#include<iostream>
using namespace std;
class Copy_construction {
public:
Copy_construction(int a = )
{
this->a = a;
cout << "这是有默认参数的构造函数!\n";
}
Copy_construction(const Copy_construction &obj)
{
cout << "这是拷贝构造函数!\n";
a = obj.a;
}
~Copy_construction()
{
cout << "一个对象被析构了!\n";
}
private:
int a;
};
Copy_construction fuc(void)
{
cout << "fuc函数!\n";
Copy_construction A;
return A;//调用拷贝构造函数,生成匿名对象
}//运行到该处,先析构对象A,匿名对象是否析构要看怎么去接
//如下所示直接调用fuc()则此时匿名对象会被立即析构
void play_empty(void)
{
fuc();
}
int main()
{
play_empty(); cout << "hello world!\n";
return ;
} 如果直接显示调用构造函数,要看怎么去接这个函数, Copy_construction(1);调用之后马上执行析构匿名对象, Copy_construction T= Copy_construction(1);不会马上析构还会转正。
test4:
修改fuc函数的返回类型为引用或者指针:
Copy_construction *fuc(void)
{
cout << "fuc函数!\n";
Copy_construction A;
return &A;
} Copy_construction &fuc(void)
{
cout << "fuc函数!\n";
Copy_construction A;
return A;
} /********返回类型为指针或者引用不会调用拷贝构造函数*********/
test5:
改变接匿名对象的方式:
#include<iostream>
using namespace std;
class Copy_construction {
public:
Copy_construction(int a = )
{
this->a = a;
cout << "这是有默认参数的构造函数!\n";
}
Copy_construction(const Copy_construction &obj)
{
cout << "这是拷贝构造函数!\n";
a = obj.a;
}
~Copy_construction()
{
cout << "一个对象被析构了!\n";
}
private:
int a;
};
Copy_construction fuc(void)
{
cout << "fuc函数!\n";
Copy_construction A;
return A;//调用拷贝构造函数,产生匿名对象
}//析构对象A,根据下面代码的接匿名对象的方式,
//此时匿名对象不仅不会马上析构,还会转正成为对象B
//从c++设计哲学上来说,这也是提高效率的一种方式,这样的设计是合理的,因为你想创建对象B,我就不用再新开辟内存了,直接用之前的匿名对象代替
void play_empty(void)
{
Copy_construction B=fuc();//这里不会调用拷贝构造函数,匿名对象直接转正了
cout << "匿名对象转正!\n";
}
int main()
{
play_empty(); cout << "hello world!\n";
return ;
}
test6:
再改变接匿名对象的方式,重写play_empty()函数:
void play_empty(void)
{
Copy_construction B;
B= fuc();
cout << "匿名对象不会转正!\n";
} //如上所示代码,此时对象B会开辟内存,在用返回的匿名对象赋值给B,将会在赋值完成之后立即析构匿名对象,这个时候匿名对象不会转正。
summary:以下情况会调用拷贝构造函数
1.直接初始化和拷贝初始化时
2.将一个对象作为实参传递给一个非引用或非指针类型的形参时
3.从一个返回类型为非引用或非指针的函数返回一个对象时
4.用花括号列表初始化一个数组的元素或者一个聚合类(很少使用)中的成员时。
c++之拷贝构造函数调用时机的更多相关文章
- C++ //拷贝构造函数调用时机//1.使用一个已经创建完毕的对象来初始化一个新对象 //2.值传递的方式给函数参数传值 //3.值方式返回局部对象
1 //拷贝构造函数调用时机 2 3 4 #include <iostream> 5 using namespace std; 6 7 //1.使用一个已经创建完毕的对象来初始化一个新对象 ...
- C++ //构造函数调用规则 //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) //析构函数(空实现) //拷贝函数(值拷贝) //2.如果我们写了有参构造函数 编译器就不会提供默认构造函数 但是会提供拷贝构造函数 //3.如果我们写了拷贝函数 编译器就不再提供 默认 有参 构造函数
//构造函数调用规则 #include <iostream> using namespace std; //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) ...
- C++派生类的拷贝构造
一. 概述 通过几个简单的实验,回顾下派生类中拷贝构造的相关知识. 环境:Centos7 64位, g++ 4.8.5 在继承中,构造器与析构器均没有被继承下来.拷贝构造,也是一种构造,也没有被继承下 ...
- C++ 构造函数、析构函数、拷贝构造、赋值运算符
之所以要把它们放在一起,是因为在使用C/C++类语言的时候,很容易混淆这几个概念(对Java来说完全没有这样的问题,表示Javaor完全没有压力). 先建立一个测试类(包含.h和.cpp) //~ P ...
- 拷贝构造和拷贝赋值、静态成员(static)、成员指针、操作符重载(day06)
十七 拷贝构造和拷贝赋值 浅拷贝和深拷贝 )如果一个类中包含指针形式的成员变量,缺省的拷贝构造函数只是复制了指针变量的本身,而没有复制指针所指向的内容,这种拷贝方式称为浅拷贝. )浅拷贝将导致不同对象 ...
- 【面试】C++类中的相关函数【构造,拷贝构造,析构,友元】
构造函数:值的初始化,可带参数,无返回值,可重载,可存在多个 析构函数:释放对象内存空间,无参数,无返回值,不可重载,只能存在一个 拷贝构造函数:拷贝对象,其形参必须是引用 1.空类会默认添加哪些东西 ...
- C++ //构造函数的分类及调用 //分类 // 按照参数分类 无参构造函数(默认构造) 有参构造函数 //按照类型分类 普通构造 拷贝构造
1 //构造函数的分类及调用 2 //分类 3 // 按照参数分类 无参构造函数(默认构造) 有参构造函数 4 //按照类型分类 普通构造 拷贝构造 5 6 #include <iostream ...
- c++拷贝构造和编译优化
#include <iostream> using namespace std; class MyClass { public: MyClass(); MyClass(int i); My ...
- java初始化构造函数调用顺序
类初始化时构造函数调用顺序: (1)初始化对象的存储空间为零或null值: (2)调用父类构造函数: (3)按顺序分别调用类成员变量和实例成员变量的初始化表达式: (4)调用本身构造函数. 例子 ...
随机推荐
- 为什么需要设置pythonpath环境变量?
# -*- coding: utf-8 -*- #python 27 #xiaodeng #为什么需要设置pythonpath环境变量? #只需设置pythonpath,从而可以从正在用的目录(也就是 ...
- tomcat7.0.27的bio,nio.apr高级运行模式(转)
一 前言 tomcat的运行模式有3种.修改他们的运行模式.3种模式的运行是否成功,可以看他的启动控制台,或者启动日志.或者登录他们的默认页面http://localhost:8080/查看其中的服务 ...
- flume的memeryChannel中transactionCapacity和sink的batchsize需要注意事项
一. fluem中出现,transactionCapacity查询一下,得出一下这些: 最近在做flume的实时日志收集,用flume默认的配置后,发现不是完全实时的,于是看了一下,原来是memery ...
- Oracle查询结果中:一列中相同的值或一列中重复的值,只显示一次
http://www.itpub.net/thread-1768915-1-1.html 问题: CREATE TABLE test(ob_id VARCHAR(32),ob_name VARCHAR ...
- 创业就是和靠谱的人一起做热爱的事 印象笔记CEO谈创业
http://www.nowamagic.net/librarys/news/detail/1502在今年美国知名创业孵化器 Y Combinator 的创业学校大会上,印象笔记(Evernote)的 ...
- php数据库操作类(转)
<?php Class DB { private $link_id; private $handle; private $is_log; private $t ...
- 关于android.view.WindowLeaked(窗体泄露)的解决方案
虽然是小问题一个,但也困扰了我一段时间,现在记下来,给自己做个备忘,也可以给其他人一个参考 view plaincopy to clipboardprint? 01-08 01:49:27.874: ...
- Python学习笔记011——内置函数eval()
1 描述 eval() 函数用来执行一个字符串表达式,并返回表达式的值 2 语法 原文 eval(expression[, globals=None[, locals=None]]) express ...
- Maven + Eclipse + Tomcat - 开启项目调试之旅(转载)
本文的读者需要拥有一些Maven基础知识和实践,如果没有,请直接绕过或者先看一些关于Maven教程,比如Juven翻译的<Maven权威指南>,google一下便知. 开门见山,首先抛出一 ...
- OAF_OAF编译代码至应用详解(案例)
201-06-01 Created By BaoXinjian