标签:拷贝构造函数 拷贝构造的调用时机 何时需要自定义拷贝构造函数
// // main.cpp // 拷贝构造函数 // // Created by 06 on 15/1/26. // Copyright (c) 2015年 黄永锐. All rights reserved. // #pragma 创建对象的时候,有可能是通过构造函数,也有可能是通过拷贝构造函数创建的。 #include <iostream> using namespace std; //日期类 class Date{ int year,month,day; public: Date(){//无参构造 cout << "日期类的构造函数" << endl; } ~Date(){ cout << "日期的析构函数" << endl; } }; //主函数 int main(int argc, const char * argv[]) { //首先创建一个对象 然后通过它来赋值. 这里到底创建了几个对象?销毁了几个对象? Date d; Date d2 = d; return 0; }
日期类的构造函数 日期的析构函数 日期的析构函数 Program ended with exit code: 0
//结果显示创建了一个对象 销毁了两个 问题出在哪里? 其实是创建了两个对象,只是有一个对象没有经过构造函数
<span style="font-size:18px;">//拷贝构造函数,如果我们自己没有写,编译器会帮我们写一个拷贝构造函数 //用同类型的对象创建对象的时候会用到拷贝构造函数,会调用d2的拷贝构造函数把d传进去 /* * Date(Date d3){ //注意这里啊,这里的参数如果是值传递,也就相当于(Date d3 = d)..这里又调用了d3的拷贝构造函数。。。。也就是说这里会导致死循环。所以在这一步要避免创建新对象,创建新对象就要调用拷贝 } * */ #pragma 拷贝构造函数里面的参数类型必须是引用 Date (Date& d3){//这里把那个对象本身传进来并没有创建新的对象 这样就不会调用拷贝了 //d3是d的引用(别名)...用同类型的对象创建对象,也可以说是用d来给d2初始化. //this在这里就代表d2 this->year = d3.year;//把传进来的对象的成员变量给新的对象的成员变量赋值 this->month = d3.month; this->day = d3.day; cout << "拷贝构造函数Date (Date& d3)" << endl; }</span>
<span style="font-size:18px;">日期类的构造函数 拷贝构造函数Date (Date& d3) 日期的析构函数 日期的析构函数 Program ended with exit code: 0</span>
const Date d; Date d2 = d;
<span style="font-size:18px;">d3.year = 2013;</span>
<span style="font-size:18px;">const Date d;</span>
Date d2 = d;
#pragma 拷贝构造函数里面的参数类型必须是引用 Date (const Date& d3){//这里把那个对象本身传进来并没有创建新的对象 这样就不会调用拷贝了 //d3是d的引用(别名)...用同类型的对象创建对象,也可以说是用d来给d2初始化. //this在这里就代表d2 // d3.year = 2013; this->year = d3.year;//把传进来的对象的成员变量给新的对象的成员变量赋值 this->month = d3.month; this->day = d3.day; cout << "拷贝构造函数Date (Date& d3)" << endl; }
日期类的构造函数 拷贝构造函数Date (Date& d3) 日期的析构函数 日期的析构函数 Program ended with exit code: 0
<span style="font-size:18px;"> this->year = d3.year;//把传进来的对象的成员变量给新的对象的成员变量赋值 this->month = d3.month; this->day = d3.day;</span>只是拿d的值给当前对象赋值。如果是指针的话,我拿d的这个指针给当前对象赋值,赋值的是个地址(浅拷贝,两个指针指向同一个对象)
<span style="font-size:18px;">//员工类 class Employee{ string name; Date *birth;//这是一个指针 public: Employee(string name):name(name){ birth = new Date;//指向堆中的一块内存 cout << "员工类的构造函数" << endl; } ~Employee(){ delete birth;//清除指向堆的空间 cout << "员工类的析构函数" << endl; } };</span>
<span style="font-size:18px;">//主函数 int main(int argc, const char * argv[]) { // Employee em("假如我是张三"); return 0; }</span>
<span style="font-size:18px;">日期类的构造函数 员工类的构造函数 日期的析构函数 员工类的析构函数 Program ended with exit code: 0</span>
<span style="font-size:18px;"> Employee em("假如我是张三"); Employee em2 = em;</span>
<span style="font-size:18px;">日期类的构造函数 员工类的构造函数 日期的析构函数 员工类的析构函数 日期的析构函数 拷贝构造函数(2824,0x7fff7399c300) malloc: *** error for object 0x100104cb0: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug (lldb) </span>
首先在创建第一个员工的时候程序没有报错。在创建第二个对象的时候就报错了,因为第二步是把第一个员工赋值的,很明显第二步只是简单的调用了拷贝构造函数,这种情况我们必须知道编译器写的拷贝构造函数做什么事情了,才能知道为什么报错了.所以先写出员工类的拷贝构造函数看看先........
标签:拷贝构造函数 拷贝构造的调用时机 何时需要自定义拷贝构造函数
原文地址:http://blog.csdn.net/love9099/article/details/43155471