C++构造函数
2022/2/9 17:17:25
本文主要是介绍C++构造函数,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
构造函数按参数为为:有参构造函数和无参构造函数
按类型分为:普通构造函数和拷贝构造函数
构造函数的三种调用方法:括号法,显示法,隐式转换法;
//括号法 Person p1; //默认构造 无参构造 Person p2(13); //有参构造 Person p3(p2); //拷贝构造 //注意:使用无参构造时不要写括号。不然系统会认为该语句是函数声明。 例:Person p1(); //显示法 Person p1; Person p2 = Person(13);//有参构造 Person p3 = Person(p2);//拷贝构造 //注意:右值的写法称为匿名对象,当前行执行完后,系统就会释放该对象。 //隐式转换法 Person p4 = 13;//相当于 Person p4 = Person(13); Person p5 = p4;//拷贝构造
C++中拷贝构造函数的调用时机:
一,一般会使用一个已创建好的对象来初始化一个新对象
Person p1; Person p2(p1); Person p3 = Person(p2); Person p4 = p3;
二,值传递方式给形参传值
void function(Person p) { } int main() { Person p1; function(p1);//这里以值传递,其实是Person temp = p1;调用拷贝构造函数 }
三,值返回方式返回局部对象
Person function() { Person p1;//创建对象 return p1;//返回局部对象 } void test() { Person p = function();//值传递实际上是用一个temp去拷贝原来的值,然后原来的局部对象被释放。temp作为返回值被接收。 }
构造函数调用规则。
如果自定义了有参构造函数,系统则不提供默认构造函数,但仍然提供拷贝构造函数。
如果自定义了拷贝构造函数,系统则不提供其他构造函数,需要的话要自己写。
/***********************************************************************/
深拷贝和浅拷贝
我们系统提供的默认拷贝构造函数是一种浅拷贝,所谓浅拷贝,其实就是简单的值拷贝,我们都知道,对象被释放的时候会调用析构函数,而析构函数的作用就是把对象的资源释放,例如你的对象有属性开辟到了堆区,析构时就需要delete释放掉。
class Person{ public: Person(string name,int age) { this->name = name; this->age = new int(age);//这个属性开辟到了堆区 } Person(const Person &p) { name = p.name; age = new int(*p.age);//深拷贝,new一块新的内存,避免重复释放同一内存 } void show() { cout << name << endl; cout << *age << endl; } ~Person() { if(age != NULL) { delete age; age = NULL; } }// private: string name; int *age; }; int main() { Person p1("hzh",21);//初始化对象 Person p2(p1); //如果不写上面的拷贝构造函数,则默认拷贝构造(浅拷贝) //这样会发送的问题,因为属性中有指针,浅拷贝时把指针指向的地址拷贝给了p2 //则两个指针指向的是同一个地址,而析构时会因为重复释放一块内存而造成错误。 return 0; }
要解决上述问题,就要自己写一个拷贝构造函数来实现深拷贝,具体操作为把开辟到堆区的属性在拷贝时重新new一块内存去存放。
本篇仅供学习交流使用,因水平有限,如有不足或错误之处,还请大家指出,欢迎大家互相讨论学习,共同进步。
这篇关于C++构造函数的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享