【原创】C++

xiaoxiao2021-02-27  241

喜欢的朋友可以关注收藏一下:  http://blog.csdn.NET/qq_31201973

本文实现了一个Shape类型并且派生出Rectangle类和Circle类,本文和上周有相似的地方也有不同,原版要求如下:

 

为下面的 Rectangle 和 Circle 类重写 getArea 虚函数。然后创建一个数组。 使用一个循环,生成 10 个 Rectangle、10 个 Circle,根据循环遍历顺序为它 们设置 no 编号,位置、长、宽、半径等其他信息取随机 1~10 之间的整数值, 然后将它们加入到创建好的数组中。最后,将这个长度为 20 的数组中所有面 积小于 50 的形状删除。将剩下的形状组成一个新的数组返回。

注意: 1. 补齐任务所需的其他函数。2. 考虑正确的内存管理。3. 使用原生数 组,不使用 vector 等容器。

class Shape { int no; public: virtual int getArea()=0; }; class Point { int x; int y; }; class Rectangle: public Shape { int width; int height; Point leftUp; }; class Circle: public Shape { Point center; int radius; };

先谈几个细节:

一、class和struct

在c++里class和struct功能很类似,但是我们一般用struct只用c语言延续的功能。

class默认是private,struct默认是public.

二、三种继承的背后

众所周知:

三种访问权限

public:可以被任意实体访问

protected:只允许子类及本类的成员函数访问

private:只允许本类的成员函数访问

 

三种继承方式

public 继承

protect 继承

private 继承

 

组合结果

基类中 继承方式 子类中

public & public继承 => public

public & protected继承 => protected

public & private继承 = > private

 

protected & public继承 => protected

protected & protected继承 => protected

protected & private继承 = > private

 

private & public继承 => 子类无权访问

private & protected继承 => 子类无权访问

private & private继承 = > 子类无权访问

而关键就在这里,基类private被子类继承是无法访问,而不是无法继承。我用运算符sizeof()运算符算了一下大小发现它是可以继承的只不过无法访问。这样除了public、private、protected还有一种隐藏的无法访问,而无法访问的成员是可以通过两种方式恢复原权限。

方法一,使用using 语句,这是C++标准建议使用的方式 如: using Base-name::member;

方法二,使用访问声明,形式为 base-class::member;, 位置在子类中适当的访问声明处。(注,只能恢复原有访问权限,而不能提高或降低访问权限)

三、出现的问题

在写程序的时候我为了保证通用性,写了重载<< ,结果在定义Shape** 数组的时候发现两种类型放到一个数组里没法访问两种类型的成员。在提交作业后在和别人讨论发现,大多数人定义了一个print的虚函数,这样实例化以后发现因为互为友元所以可以访问自身的成员了,而重载<< 内也可以调用print函数。

而我因为无法访问,定义了一个struct包含了Rectangle和Circle类型,然后就可以访问了。

四、c++11

涉及c++11的问题请看第一周文章的解释。

五、相关文章

1.http://www.cppblog.com/shongbee2/archive/2009/04/01/78554.html#post

2.http://www.cnblogs.com/ustc11wj/archive/2012/08/11/2637316.html

3.http://www.cnblogs.com/bizhu/archive/2012/07/20/2601303.html

4.http://blog.csdn.net/stay4it/article/details/70879884

5.http://www.cppblog.com/airtrack/archive/2012/09/16/190828.aspx

6.http://blog.csdn.net/huang_xw/article/details/8764346

7.http://www.cnblogs.com/york-hust/archive/2012/06/01/2530799.html

8.http://www.cnblogs.com/ider/archive/2011/07/31/cpp_cast_operator_part4.html

9.http://blog.sina.com.cn/s/blog_9ce5a1b5010131nj.html

10.http://blog.csdn.net/weizhee/article/details/562833

11.http://wenda.so.com/q/1382868367063692?src=140

六、我的代码

// 本文件名 class_define.h 我的编程环境VS2013 /* 本程序的注释代表仅代表个人理解,不一定完全正确,全是我亲自敲上去的,如有错误请联系我。 */ /* 本程序随机数生成器类和变参数print()函数使用了C++11 的标准,可能有的编译器不能编译通过,我会截图一下编译结果 */ /* 本程序没有使用原型的设计模式,而是采用结构体的模式 */ #ifndef __CLASS_DEFINE_H__ #define __CLASS_DEFINE_H__ #include<iostream> #include<random> using namespace std; const double PI = 3.1415926; //π namespace guo { template<typename T> class Shape { private: int no; //给每个Shape类及其子类按创建对象顺序标号 public: static int count; //统计当前存活的Shape类及其子类按创建对象(数目) Shape() :no(++count) { ; } //构造函数 Shape(const Shape& other) :no(++count) { ; } //拷贝构造函数 Shape& operator=(const Shape& other) { if (this == &other) { return *this; } else { no = other.no; return *this; } } ~Shape() { count--; } //当前存活的Shape类及其子类按创建对象(数目减一) int get_no() const { return this->no; } static void set_count(const int x) { count = x; } virtual T getArea() = 0; //得到面积 }; class Point { private: int x; int y; public: Point(int x1 = 0, int y1 = 0) : x(x1), y(y1) {; } // 构造函数,支持对象符合 int get_x() const { return x; } int get_y() const { return y; } }; class Rectangle : public Shape<double> { private: int width; int height; Point leftUp; public: Rectangle(int width1 = 0, int height1 = 0, int x1 = 0, int y1 = 0); //构造函数 //Rectangle(const Rectangle& other); //拷贝构造函数 Rectangle& operator=(const Rectangle& other); //拷贝赋值函数 ~Rectangle(); //析构函数 只声明不定义会出无法解析的错误 int get_width() const { return width; } int get_height() const { return height; } const Point& get_leftUp() const { return leftUp; } virtual double getArea() { return (this->height)*(this->width); } //得到面积 friend Rectangle& __doequ(Rectangle*, const Rectangle&); //赋值实际运算函数 //int get_no() const { return no; } }; class Circle : public Shape<double> { private: Point center; int radius; public: Circle(int radius1 = 0, int x2 = 0, int y2 = 0); //构造函数 ~Circle(); //析构函数 只声明不定义会出无法解析的错误 Circle& operator=(const Circle& other); //拷贝赋值函数 int get_radius() const { return radius; } const Point& get_center() const { return center; } virtual double getArea() { return PI*(this->radius)*(this->radius); } //得到面积 }; class Rand_int //等概率整数的随机数生成器 随机生成器由引擎(负责生成一组随机值或者伪随机数)和一种分布(负责把引擎产生的值映射到某个数学分布上) { public: Rand_int(int low, int high) : dist{ low, high } { ; } //构造函数 初始化随机数范围 int operator()(){ return dist(re); } //操作符() 重载 得到一个随机int private: default_random_engine re; //默认随机引擎 uniform_int_distribution<> dist;//分布:生成的所有整数概率相等 }; typedef struct twotype { Rectangle p; Circle q; }twotype; /************************************ The Rectangle class member function define. ************************************/ inline Rectangle::Rectangle(int width1, int height1, int x1, int y1) : width(width1), height(height1), leftUp(Point(x1, y1)) //Rectangle类的构造函数,需要Point有构造函数 { ; } inline Rectangle::~Rectangle() { ; } Rectangle& Rectangle::operator=(const Rectangle& other) { if (this == &other) { return *this; } Shape<double>::operator=(other); this->width = other.width; this->height = other.height; this->leftUp = other.leftUp; return *this; } /****************************************************************************************************************************************************************/ /************************************ The Circle class member function define. ************************************/ inline Circle::Circle(int radius2, int x2, int y2) :radius(radius2), center(Point(x2, y2)) { ; } inline Circle::~Circle() { ; } Circle& Circle::operator=(const Circle& other) //拷贝赋值函数 { if (this == &other) { return *this; } Shape<double>::operator=(other); center = other.center; radius = other.radius; return *this; } /****************************************************************************************************************************************************************/ /* print函数 */ void print() { ; } template<class type, class... types> //class 的定义和 typename 类似 都是说这个模板参数定义的是一个类,而不是变量.class type 和 class... types type 和 types 是模式 , ... 是包扩展 void print(const type& x, const types&... next) { cout << x << endl; print(next...); } /****************************************************************************************************************************************************************/ //Rectangle** create_array(Rectangle **buff, const int& count) //{ // Rand_int randx{1,10}; // for (int i = 0; i < count; i++) // { // buff[i] = new Rectangle(randx(), randx(), randx(), randx()); // } // //for (int i = (count / 2); i < count; i++) // //{ // // buff[i] = new Circle(randx(), randx(), randx()); // //} // return buff; //} //Circle** create_array(Circle **buff, const int& count) //{ // Rand_int randx{ 1, 10 }; // for (int i = 0; i < count; i++) // { // buff[i] = new Circle(randx(), randx(), randx()); // } // return buff; //} ostream& operator<<(ostream& os, guo::Rectangle& rec) //The Rectangle class operator function. { return os << ' ' << "NO." << rec.get_no() << ' ' << '(' << "长=" << rec.get_height() << ',' << "宽=" << rec.get_width() << ',' << "面积=" << rec.getArea() << ')' << " " << "坐标=" << '(' << rec.get_leftUp().get_x() << ',' << rec.get_leftUp().get_y() << ')' << endl; } ostream& operator<<(ostream& os, guo::Circle& cir) //The Rectangle class operator function. { return os << ' ' << "NO." << cir.get_no() << ' ' << '(' << "半径=" << cir.get_radius() << ',' << "面积=" << cir.getArea() << ')' << " " << "坐标=" << '(' << cir.get_center().get_x() << ',' << cir.get_center().get_y() << ')' << endl; } twotype* create_array(twotype *buff, twotype *buff2, const int& count) { Rand_int randx{ 1, 10 }; print("初次创建:"); for (int i = 0; i < count; i++) { Rectangle a(randx(), randx(), randx(), randx()); Circle b(randx(), randx(), randx()); buff[i].p = a; buff[i].q = b; cout << buff[i].p << endl; cout << buff[i].q << endl; } print("删除面积小于之后:"); for (int i = 0; i < count; i++) { if (buff[i].p.getArea() >= 50) { buff2[i].p = buff[i].p; cout << buff2[i].p << endl; } if (buff[i].q.getArea() >= 50) { buff2[i].q = buff[i].q; cout << buff2[i].q << endl; } } return buff; } } #endif

 

// 本文件名 main.h 我的编程环境VS2013 /* 本程序的注释代表仅代表个人理解,不一定完全正确,全是我亲自敲上去的,如有错误请联系我。 */ /* 本程序随机数生成器类和变参数print()函数使用了C++11 的标准,可能有的编译器不能编译通过,我会截图一下编译结果 */ /* 本程序没有使用原型的设计模式,而是采用结构体的模式 */ #include<iostream> #include"class_define.h" #include<random> using namespace std; int guo::Shape<double>::count = 0; const int x = 10; int main(void) { //guo::Rectangle r1{ 2, 2, 1, 1 }; //guo::Circle c1{ 2, 3, 4 }; //guo::Rectangle *a1[x]; //guo::Circle *a2[x]; guo::twotype a3[x]; guo::twotype buff2[x]; //cout << "矩形r1:" << r1 << endl; //cout << "圆形c1:" << c1 << endl; //cout << "sizeof(r1)=" <<sizeof(r1) << endl; //继承证明验证 /*guo::print("请输入创建数组的大小(20):");*/ //自定义print()函数验证 //cin >> x; guo::create_array(a3, buff2, x); //创建删除一体 /*printArray(a3, x);*/ getchar(); getchar(); return 0; }

七、运行截图

 

转载请注明原文地址: https://www.6miu.com/read-11024.html

最新回复(0)