以下为定义的图形继承体系:
class Shape{
public:
// . . .
virtual double area(){}
};
class Circle:public Shape{
public:
double area(){…}
// . . .
};
class Triangle:public Shape{
public:
double area(){…}
// . . .
};
// . . .
以下为容器类:
class Manage{
shape *a[100];
public:
// . . .
}
要求完成Manage类的拷贝构造函数,实现深度拷贝;可以改动所有的类,并给出main函数测试程序。
(最好能教一下)
// Q766790.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class Shape{
public:
virtual double area() = 0;
};
class Circle: public Shape{
public:
double r;
double area(){
return 3.14 * r * r;
}
};
class Triangle: public Shape{
public:
double h;
double e;
double area(){
return h * e / 2.0;
}
};
class Manage{
private:
Shape *a[100];
int n;
public:
int GetCount()
{
return n;
}
Manage() { n = 0; }
void Add(Shape * shp)
{
a[n++] = shp;
}
Shape* Get(int index)
{
return a[index];
}
Manage(Manage& other)
{
cout << "copy ctor" << endl;
for (int i = 0; i < other.n; i++)
a[i] = other.a[i];
n = other.n;
}
};
int main()
{
Circle c1, c2;
c1.r = 1.2;
c2.r = 10;
Triangle t1, t2;
t1.e = 1;
t1.h = 2;
t2.e = 10;
t2.h = 5;
Manage m1;
m1.Add(&c1);
m1.Add(&c2);
m1.Add(&t1);
Manage m2 = m1;
m2.Add(&t2);
cout << m1.GetCount() << endl;
cout << m2.GetCount() << endl;
for (int i = 0; i < m2.GetCount(); i++)
cout << "area: " << m2.Get(i)->area() << endl;
return 0;
}
copy ctor
3
4
area: 4.5216
area: 314
area: 1
area: 25
Press any key to continue
稍微讲解一下,具体你要看书
构造函数的作用是构造一个对象
它的定义方式是,不要写返回值类型,函数名和类同名
Manage() { n = 0; }
Manage(Manage & other)
{
for (int i = 0; i < other.n; i++)
a[i] = other.a[i];
n = other.n;
}
这两个就是构造函数
拷贝构造函数的意思是,带有一个参数是另一个这个类的对象
Manage(Manage & other)
这个就是拷贝构造函数
Manage m2 = m1;
这里调用了拷贝构造函数
也可以写
Manage m2(m1);
深度拷贝的意思是,将原来的对象的数组的值依次拷贝过来,而不是仅仅让这个对象的a指向被拷贝的那个对象。
可以看出,给m2再增加shape,则m1的数量不会发生变化。
#include<iostream>
using namespace std;
class Shape {
public:
// . . .
virtual double area() const { return 0; }
virtual Shape* clone() const { return new Shape(*this); }
//virtual Shape* clone() = 0;
//如果不打算创建Shape类型的对象,下面这样就挺好的
};
class Circle :public Shape {
public:
Circle(double radius) :r(radius) {}
Shape* clone()const override { return new Circle(*this); }
double area() const override { return 3.14 *r*r; }
// . . .
private:
double r;
};
class Triangle :public Shape {
public:
Triangle(double base, double height) :a(base), h(height) {}
double area() const { return a * h / 2.0; }
Shape* clone()const override { return new Triangle(*this); }
// . . .
private:
double a;
double h;
};
// . . .
//以下为容器类:
class Manage {
Shape *a[100];
size_t _Size;
public:
// . . .
Manage() :_Size(0) {}
Manage(const Manage&_Right) {
for (size_t i = 0; i < _Right._Size; ++i)
a[i] = _Right.a[i]->clone();
_Size = _Right._Size;
}
void push_back(Shape* _Ptr)
{
a[_Size] = _Ptr;
++_Size;
//就不管它满了的情况了
}
Shape* operator[](size_t i)
{
return a[i];
//就不检查i的大小了
}
void pop_back()
{
delete a[--_Size];
}
~Manage()
{
for (size_t i = 0; i < _Size; ++i)
delete a[i];
}
};
int main()
{
Manage m1;
//m1添加两个元素
m1.push_back(new Circle(3.0));
m1.push_back(new Triangle(2.0, 3.0));
//m1拷贝到m2
Manage m2 = m1;
//把m1里的元素删掉
m1.pop_back();
m1.pop_back();
//访问m2的元素
cout << "m2[0]'s area is " << m2[0]->area() << endl;
cout << "m2[1]'s area is " << m2[1]->area() << endl;
return 0;
}
m2[0]'s area is 28.26
m2[1]'s area is 3
想要通过基类的指针拷贝派生类,只能用虚函数,而且只能在堆里拷贝(因为为无法通过基类的指针知道派生类的大小,不知道要分配多少内存)。
所以使用了一个clone函数来拷贝