【发布时间】:2012-10-17 11:15:47
【问题描述】:
我有问题。我需要克隆包含指针的对象类。问题的一个示例在以下代码中:
#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <vector>
class CPoint
{
protected:
int m_x;
int m_y;
int *m_p;
public:
CPoint();
CPoint(int x, int y);
~CPoint();
CPoint* clone();
static CPoint* clone(CPoint& p);
int getX();
int getY();
void setX(int x);
void setY(int y);
void toString();
};
int CPoint::getX()
{
return m_x;
}
int CPoint::getY()
{
return m_y;
}
void CPoint::setX( int x )
{
m_x = x;
}
void CPoint::setY( int y )
{
m_y = y;
}
void CPoint::toString()
{
std::cout << "(" << m_x << ", " << m_y<< ", " << *m_p << ")" << std::endl;
}
CPoint::CPoint( int x, int y )
{
m_x = x;
m_y = y;
m_p = new int();
*m_p = x + y;
}
CPoint::CPoint()
{
m_p = new int();
*m_p = 1000;
}
CPoint* CPoint::clone()
{
CPoint *p = new CPoint();
*p = *this;
return p;
}
CPoint* CPoint::clone( CPoint& p )
{
CPoint *q = new CPoint();
*q = p;
return q;
}
CPoint::~CPoint()
{
if (m_p) {
delete m_p;
m_p = NULL;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
CPoint *p1 = new CPoint(10, 20);
CPoint *p2 = new CPoint(30, 40);
p1->toString();
p2->toString();
CPoint *p3;
p3 = CPoint::clone(*p1);
p3->toString();
CPoint *p4;
p4 = p2->clone();
p4->toString();
p1->setX(50);
p1->setY(60);
p2->setX(80);
p2->setY(90);
p3->toString();
p4->toString();
delete p1;
delete p2;
delete p3;
delete p4;
int a;
std::cin >> a;
return 0;
}
变量m_p 的问题。在p3和p4上克隆对象p1和p2时,内存地址p1和p3不同,但m_p地址相同。显然,当删除p1,p3 删除失败。与p2 和p4 是一样的。
如何克隆 CPoint 类对象?
【问题讨论】:
-
m_p到底是什么是?整数还是数组?如果是前者,为什么不只是int?如果是后者,为什么不是std::vector,因为你已经有了#include <vector>?另外,为什么clone而不是复制构造函数?这是某种层次结构中的多态基类吗?如果是这样,为什么析构函数不是虚拟的? -
在这个例子中是一个整数,但可以是任何类型。我的问题是克隆一个包含指向另一种类型的指针的对象。谢谢。
-
您不需要克隆复制构造函数的用途。当我们在这里时,不要执行 tostring()。这就是
operator<<的用途。另请注意,由于您不遵守三人规则,您的班级从根本上被破坏了。故事的寓意不要在语言“B”中使用语言“A”中的模式,它只是行不通。学习使用语言“B”及其习语。