//
// 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