关于C++默认拷贝构造函数

我建了一个工程,定义了两个类,分别是Person和Date,如下(注:类的声明和实现分开的),代码如下:Data的声明:#ifndefDATE_H#defineDATE_... 我建了一个工程 ,定义了两个类,分别是Person和Date,如下(注:类的声明和实现分开的),代码如下:
Data的声明:
#ifndef DATE_H
#define DATE_H
class Date
{
public:
Date(int,int,int);
int getYear();
void setYear(int);
private:
int year;
int month;
int day;
};
#endif

Date的实现:
#include"Date.h"
Date::Date(int newYear,int newMonth,int newDay)
{
year = newYear;
month = newMonth;
day = newDay;
}
int Date::getYear()
{
return year;
}
void Date::setYear(int newYear)
{
year = newYear;
};

Person的声明:
#include"Date.h"
class Person
{
public:
Person(int,int,int,int);
~Person();
int getId();
Date* getBirthDate();
private:
int id;
Date* birthDate;
};

Person的实现:
#include"Person.h"
Person::Person(int id,int year,int month,int day)
{
this->id = id;
birthDate = new Date(year,month,day);
}
int Person::getId()
{
return id;
}
Date* Person::getBirthDate()
{
return birthDate;
}
Person::~Person()
{
delete birthDate;
};

带有主函数的程序:
#include<iostream>
#include"Person.h"
using namespace std;
void displayPerson(Person &person1,Person &person2)
{
cout<<"\tPerson1 id:"<<person1.getId()<<endl;
cout<<"\tperson1 birth year:"<<person1.getBirthDate()->getYear()<<endl;
cout<<"\tPerson2 id:"<<person2.getId()<<endl;
cout<<"\tperson2 birth year:"<<person2.getBirthDate()->getYear()<<endl;
}
int main()
{
Person person1(111,1970,5,3);
Person person2(222,2000,11,8);
cout<<"After creating person1 and person2"<<endl;
displayPerson(person1,person2);

person1 = Person(person2);
cout<<"\nAfter copying person2 to person1"<<endl;
displayPerson(person1,person2);

person2.getBirthDate()->setYear(1963);
cout<<"\nAfter modifying person2's birthDate"<<endl;
displayPerson(person1,person2);
cout<<"\n"<<(person1.getBirthDate()==person2.getBirthDate())<<endl;
return 0;
}

编译执行后显示

我用的VC++6.0,程序是照着书给的问题编的,编完执行老出错,后来对照答案检查了好多遍,的确没错 , 不知道是编译器的问题还是怎么,我没办法了,望好心人过来帮帮忙。
展开
 我来答
千江月success
推荐于2016-04-12 · TA获得超过827个赞
知道小有建树答主
回答量:1031
采纳率:100%
帮助的人:987万
展开全部
Person::~Person()
{
//delete birthDate;
}

不要自己定义析构函数
如果数据成员有new分配的,因为析构函数里面有delete,如果是默认构造函数,那就是浅复制了,那最后2个类对象调用析构函数的时候,同一个内存会释放2次,然后出错啊。

但是默认的析构函数析构就是正确的。。
---------------------------------------
目前解决问题
------------------------------------
我先看看有没有内存泄露。。。一会再答。。。
------------------------
查看了一下,有内存泄露
------------------
如果一个类中有指针成员,使用缺省的复制构造函数初始化对象就会出现问题。
--------------------------------------------
把析构函数删了会有内存泄露。。。。。
------------------------------------
修改如下:
//Date.h
#ifndef DATE_H
#define DATE_H
class Date
{
public:
Date(int,int,int);
int getYear() const;
void setYear(int);
int getMonth() const;
void setMonth(int);
int getDay() const;
void setDay(int);
private:
int year;
int month;
int day;
};
#endif
----------------------
//Date.cpp
#include"Date.h"
Date::Date(int newYear,int newMonth,int newDay)
{
year = newYear;
month = newMonth;
day = newDay;
}
int Date::getYear() const
{
return year;
}
void Date::setYear(int newYear)
{
year = newYear;
}
int Date::getMonth() const
{
return month;
}
void Date::setMonth(int newMonth)
{
this->month = newMonth;
}
int Date::getDay() const
{
return day;
}
void Date::setDay(int newDay)
{
this->day = newDay;
}
-----------------------
//Person.h
#include"Date.h"
class Person
{
public:
Person(int,int,int,int);
~Person();
int getId();
Date* getBirthDate() const;
Person(const Person &rhs);
Person& operator=(const Person& rhs);
private:
int id;
Date* birthDate;
};
----------------
//Person.cpp
#include"Person.h"
Person::Person(int _id,int year,int month,int day):id(_id), birthDate(new Date(year,month,day))
{
}
int Person::getId()
{
return id;
}
Date* Person::getBirthDate() const
{
return birthDate;
}
Person::~Person()
{
if(birthDate)
delete birthDate;
birthDate = 0;
}
Person::Person(const Person& rhs)
{
this->id = rhs.id;
Date *date = rhs.getBirthDate();
this->birthDate = new Date(date->getYear(), date->getMonth(), date->getDay());
}
Person& Person::operator=(const Person& rhs)
{
delete birthDate;
this->id = rhs.id;
Date *date = rhs.getBirthDate();
this->birthDate = new Date(date->getYear(), date->getMonth(), date->getDay());
return *this;
}
-----------------------
//main.cpp
#include<iostream>
#include"Person.h"
using namespace std;
#include <assert.h>
#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif
void Exit()
{
int i = _CrtDumpMemoryLeaks();
assert( i == 0);
}
void displayPerson(Person &person1,Person &person2)
{
cout<<"\tPerson1 id:"<<person1.getId()<<endl;
cout<<"\tperson1 birth year:"<<person1.getBirthDate()->getYear()<<endl;
cout<<"\tPerson2 id:"<<person2.getId()<<endl;
cout<<"\tperson2 birth year:"<<person2.getBirthDate()->getYear()<<endl;
}
int main()
{
atexit(Exit);
Person person1(111,1970,5,3);
Person person2(222,2000,11,8);
cout<<"After creating person1 and person2"<<endl;
displayPerson(person1,person2);
person1 = Person(person2);
cout<<"\nAfter copying person2 to person1"<<endl;
displayPerson(person1,person2);
person2.getBirthDate()->setYear(1963);
cout<<"\nAfter modifying person2's birthDate"<<endl;
displayPerson(person1,person2);
cout<<"\n"<<(person1.getBirthDate()==person2.getBirthDate())<<endl;
return 0;
}
-----------------------------
这个main.cpp可以检测内存泄露。。。
--------------
假设不要的就是你原来的。。。
欢乐多Ek
2013-02-01 · TA获得超过478个赞
知道小有建树答主
回答量:477
采纳率:0%
帮助的人:448万
展开全部
person1 = Person(person2);
这里的信息量很大,首先通过person2对象创建了一个临时对象,然后事情并不是想象中的那样,这个临时对象被析构掉了!!也就是person2.birthDate 被delete了!!!!
然后将一个被析构掉的临时对象再次通过默认=复制到person1。。。。
然后结尾再对person2析构的话,就delete 两次,所以报错。
追问
谢谢哈,我把那个析构函数删了,果然可以了。然后大侠你能不能再帮我讲一下那个析构函数是怎么回事,析构函数会被自动调用吗 ? 我对你说的临时对象也不是太懂,我看的这本书讲的匿名对象应该就是你说的临时对象吧,你再指点指点我吧,拜托了!
追答
Person(person2)就是调用拷贝构造函数创建一个临时对象,然后按理说应该调用operator =()进行复制,但是你这里没有重载,这个临时对象就被析构了,然后再调用默认的operator = () 进行复制,当然结果也就错了。

至于为什么你没有重载等号它就先析构再调用默认等号运算符,这个我也不是很清楚。

反正你记住临时对象就是用完扔的东西。

_____________________________________

对不起上面误导你了,的确是先调用ooerator = () 再析构。
只是因为你没有自定义operator = () 然后复制过去的是临时对象的成员指针,然后紧接着析构后这个指针不复存在,当然,这个指针就是person2.birthDate 。所以。。你懂得。。。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
316513296
2013-02-01 · TA获得超过111个赞
知道答主
回答量:99
采纳率:100%
帮助的人:117万
展开全部
主要错误有两处,若具体修改,这段代码就面目全非了
1:person1 = Person(person2); 这句有问题 “=”这个运算符 在Person这个类中没有重载,因此,即使Person(person2); 这样进行强制转换(也不需要强制转换,他们类型一致)也不可以这样使用。
将person1 = Person(person2);这句话注释掉 就不会报错了。
2:cout<<"\n"<<(person1.getBirthDate()==person2.getBirthDate())<<endl;这段代码也是 运算符重载的问题 “==” Date 这个类 没有 对运算符 进行重载 因此 person2.getBirthDate())它会返回一个Date 类型的地址。而且若person2与person1指向的地址不相同,那么这个值永远为0。希望可以帮到你。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友8201691
2013-02-01 · TA获得超过386个赞
知道小有建树答主
回答量:281
采纳率:0%
帮助的人:176万
展开全部
#include<iostream>是不是少了个.h?我是新手!!求帮忙
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式