【题目】实现一个名为SimpleCircle的简单圆类。其数据成员int* itsRadius为一个指向其半径值的指针,存放其半径值。设计对数据成员的各种操作,给出这个类的完整实现并测试这个类。
根据题意,可以有以下几个功能:①根据半径计算面积、周长;②对半径进行运算等等。
<使用平台:Microsoft visual studio>
代码如下:
#include<iostream>
#include<cmath>
using namespace std;
const double PI = 3.1415;
class SimpleCircle
{
public:
SimpleCircle(int* itsradius):itsRadius(itsradius) //构造函数
{
cout << "Constructor called." << endl;
}
SimpleCircle() //无参默认构造函数
{
itsRadius = new int(); //注释①
cout << "Default Constructor called." << endl;
}
SimpleCircle(SimpleCircle& circle) //拷贝构造函数,用来初始化另外的对象
{
itsRadius = new int(*circle.itsRadius); //此处同上注释①
cout << "Calling the constructor..." << endl;
}
~SimpleCircle()
{
cout << "Destructor called." << endl;
}
void get_itsradius(); //显示出圆的半径
void get_itsarea(); //计算出圆的面积
void get_itscircle(); //计算出圆的周长
void change_itsradius(int num); //改变圆的半径到某个值
void add_itsradius(); //给圆的半径增加值
private:
int* itsRadius;
};
void SimpleCircle::get_itsradius() //显示出圆的半径
{
cout << endl << "the radius now is: " << *itsRadius << endl;
}
void SimpleCircle::get_itsarea() //计算出圆的面积
{
cout << "the area is: " << 2 * PI * pow(*itsRadius, 2) << endl;
}
void SimpleCircle::get_itscircle() //计算出圆的周长
{
cout << "the circle is: " << 2 * PI * (*itsRadius) << endl;
}
void SimpleCircle::change_itsradius(int num) //改变圆的半径到某个值
{
*itsRadius = num;
cout << endl << "After changing..." << endl << endl << "the radius now is: " << *itsRadius << endl;
cout << "The change_itsradius has finished its function." << endl;
}
void SimpleCircle::add_itsradius() //给圆的半径增加值
{
string q;
int n = 0;
cout << endl << "now we are in the function add_itsradius——";
cout << endl << "Do you want to add some numbers to the radius?" << endl << "yes or no:";
cin >> q;
while(q != "yes"&&q != "no")
{
cout << "Invalid inputs!! please enter again" << endl;
cin >> q;
}
if (q == "yes")
{
cout << "please enter the numbers which will be added later:";
cin >> n;
}
else if (q == "no")
{
cout << "The programe is over,thank you for testing." << endl;
}
cout << endl << "Congratulations! The final radius is: " << (*itsRadius)+n << endl;
}
int main()
{
int r = 1;
int* radius = &r;
SimpleCircle mycircle1(radius); //调用含参的构造函数
mycircle1.get_itsradius();
mycircle1.get_itsarea();
mycircle1.get_itscircle();
mycircle1.change_itsradius(5); //调用change函数将radius改变到某个值再进行计算
mycircle1.get_itsarea();
mycircle1.get_itscircle();
mycircle1.add_itsradius(); //调用add函数给radius加值再进行计算
mycircle1.get_itsarea();
mycircle1.get_itscircle();
cout << endl << "****************TESTING****************" << endl;
SimpleCircle mycircle2; //调用无参默认构造函数
mycircle2.get_itsradius(); //验证
mycircle2.get_itsarea();
mycircle2.get_itscircle();
mycircle2.change_itsradius(3);
mycircle2.get_itsradius();
mycircle2.get_itsarea();
mycircle2.get_itscircle();
mycircle2.add_itsradius();
SimpleCircle mycircle3(mycircle1); //调用拷贝构造函数
mycircle3.get_itsradius(); //验证
mycircle3.get_itsarea();
mycircle3.get_itscircle();
return 0;
}
输出结果如下
- 完整结果:
- 对于add函数的不同情况:(此处省略默认构造函数和拷贝构造函数的测试结果)
【易错点】
对于代码中注释①的解释:局部变量出了其作用域后内存单元就被系统回收,但是指针可以不正确访问,指向的为随机值。
//定义一个局部变量
SimpleCircle() //无参默认构造函数
{
int rr = 8;
itsRadius = &rr; //局部变量出了其作用域后内存单元就被系统回收。
cout << "Default Constructor called." << endl;
}
//优化方案
SimpleCircle() //无参默认构造函数
{
itsRadius = new int(); //给其分配动态内存空间。
cout << "Default Constructor called." << endl;
}
【注】
- 其实如果采用上述定义一个局部变量的方法,数据成员int* itsRadius仍可以访问原先局部变量rr所在的位置,但是此时这个位置的内容已经被系统回收了,因此会由系统随机分配,从而出现随机值。类比于
有趣的说法↑
因此优化前的写法运行后,change_itsradius函数在上述写法中可以运行成功(在这个函数里有对itsRadius的内容分配,另:解释在下文),而add_itsradius函数运行结果出现随机值(即上述【注】) 。
- change_itsradius函数的写法问题
SimpleCircle() //无参默认构造函数
{
int rr = 8;
itsRadius = &rr; //局部变量出了其作用域后内存单元就被系统回收。
cout << "Default Constructor called." << endl;
}
//改变圆的半径到某个值
/*写法①*/
void SimpleCircle::change_itsradius(int num)
{
*itsRadius = num;
cout << endl << "After changing..." << endl << endl << "the radius now is: " << *itsRadius << endl << endl;
}
/*写法②*/
void SimpleCircle::change_itsradius(int num)
{
itsRadius = #
cout << endl << "After changing..." << endl << endl << "the radius now is: " << *itsRadius << endl << endl;
}
写法①:直接将num的值给了itsRadius指向的内容,相当于给itsRadius进行内容分配,因此出了change_itsradius函数之后,虽然num作为局部变量内存单元被回收,itsRadius指向的内容已经分配了num的值,因此在求面积和周长时可以正常使用;
写法②【不推荐书写】:itsRadius指向num,出了函数之后,num的内存单元被系统回收,(与上述【注】同理)指针可以<不正确>访问,指针指向的位置由系统随机分配,此时出现的就是随机值。{解决办法:分配动态内存空间}相比较而言,推荐写法①。