首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

很诡异的指针有关问题

2013-11-21 
很诡异的指针问题问题有点乱,我理一理慢慢表述下首先是一个Person类,代码如下#include Date.hclass Pers

很诡异的指针问题
问题有点乱,我理一理慢慢表述下
首先是一个Person类,代码如下

#include "Date.h"

class Person
{
public:
Person(int id, int year, int month, int day);
Person(Person &);   // 问题出在这个方法里
~Person();
int getId();
Date* getBirthDate();  // return the pointer of the object

private:
int id;
Date* birthDate;  // The pointer of the object
};

可以看到里面有Date类,代码如下
#ifndef DATE_H
#define DATE_H

class Date{
public:
Date(int newYear, int newMonth, int newDay);
int getYear();
void setYear(int year);

private:
int year;
int month;
int day;
};

#endif

我把Person类的拷贝方法重写了
Person::Person(Person &person){
id = person.id;
Date *p = person.getBirthDate();
birthDate = new Date(*p);  // 调试的时候一切正常
}

调用了
Person person1(111, 1970, 5, 3);
Person person2(222, 2000, 11, 8);
        person1 = Person(person2);  // Copy person2 to person1

就在调试的时候Person(person2)这个方法内部还是正常的,
返回的Person类里的数据也还是和Person2一样,可一到执行person1 = Person()时
地址没有变化,Person类里面的Date部分地址也没变,
当然Person下的id也没变是正常的,就是Date地址下的值全部是随机值了
这是什么原因导致的 指针
[解决办法]
引用:
Quote: 引用:

你是不是少写了一个operator =?

才学C++,有必要写一个operator =?吗


这里必须要写一个吧!因为有person1 = Person(person2) 这个操作的!
写一个=的重载吧!
[解决办法]
Person::Person(Person &person){
    id = person.id;
    Date *p = person.getBirthDate();
    birthDate = new Date(*p);  //得释放一下birthDate原来的内存呀
}
[解决办法]
基本问题搞清楚了
person1 = Person(person2);
你先构造了一个临时Person变量,然后赋值给person1。
但是因为你没有重写operator=,所以这一步的赋值是一个浅拷贝过程,你把临时变量里面的birth指针复制给了person1,但是临时变量马上就析构了,临时变量里面的birth指针指向的birth对象也肯定析构了(我相信你会在Person的析构函数中实现这个delete),所以person1中的birth指针变成了野指针。
然后,就没有然后了。
[解决办法]

#include <cstdio>
#ifndef DATE_H
#define DATE_H

class Date{
public:
Date(int newYear, int newMonth, int newDay) : year(newYear), month(newMonth), day(newDay){}
int getYear(){return year;}
void setYear(int newYear){year=newYear;}

private:
int year;
int month;
int day;
};

#endif
//#include "Date.h"

class Person
{
public:
Person(int id, int year, int month, int day) : id(id), birthDate(new Date(year, month, day)){}
Person(Person &person){
id = person.id;
Date *p = person.getBirthDate();
birthDate = new Date(*p);  // 调试的时候一切正常
}
~Person(){delete birthDate;}
int getId(){return id;}
Date* getBirthDate(){return birthDate;};  // return the pointer of the object

Person& operator = (const Person& other)
{
Date* temp = new Date(*other.birthDate);
delete birthDate;
birthDate = temp;
id = other.id;
return *this;
}
private:
int id;
Date* birthDate;  // The pointer of the object
};
int main()
{
Person person1(111, 1970, 5, 3);
Person person2(222, 2000, 11, 8);
    person1 = Person(person2);  // Copy person2 to person1
printf("%d\n", person1.getBirthDate()->getYear());
return 0;
}



楼主33楼的问题在于
Date* getBirthDate()
不是常函数(后面要长const小尾巴的才是常函数)
而Person& Person::operator=(const Person& person)
中形参person是一个常引用,所以
birthDate = new Date(*(person.getBirthDate()));
不能编译过,因为不能直接调用常函数。

在这里,不需要通过getBirthDate来访问birthDate,如我10楼代码,没有用getBirthDate。

另一方面,代码没有判断this和另一个操作数是不是同一个,每次先保证new一个birthDate出来,再
释放已有的,然后拷贝id,指针赋值,保证这个时候不出错。

热点排行