20220215 最后更新时间:2022年02月15日 ## 重载函数 重载运算符 ### 函数重载 ```c++ #include using namespace std; class printData { public: void print(int i) { cout << "整数为: " << i << endl; } void print(double f) { cout << "浮点数为: " << f << endl; } void print(char c[]) { cout << "字符串为: " << c << endl; } }; int main(void) { printData pd; // 输出整数 pd.print(5); // 输出浮点数 pd.print(500.263); // 输出字符串 char c[] = "Hello C++"; pd.print(c); return 0; } ``` 除了单个的形参数据类型不同的情况,还可以多个形参数据类型不同/数据类型相同但不同数据类型顺序不同吗 ```c++ #include using namespace std; class printData { public: void print(int i,double f) { cout << "整数为: " << i << "\t" << f << endl; } void print(double f,int i) { cout << "浮点数为: " << f << "\t" << i < using namespace std; class Box { public: double getVolume(void) { return length * breadth * height; } void setLength( double len ) { length = len; } void setBreadth( double bre ) { breadth = bre; } void setHeight( double hei ) { height = hei; } // 重载 + 运算符,用于把两个 Box 对象相加 Box operator+(const Box& b) { Box box; box.length = this->length + b.length; box.breadth = this->breadth + b.breadth; box.height = this->height + b.height; return box; } private: double length; // 长度 double breadth; // 宽度 double height; // 高度 }; // 程序的主函数 int main( ) { Box Box1; // 声明 Box1,类型为 Box Box Box2; // 声明 Box2,类型为 Box Box Box3; // 声明 Box3,类型为 Box double volume = 0.0; // 把体积存储在该变量中 // Box1 详述 Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); // Box2 详述 Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); // Box1 的体积 volume = Box1.getVolume(); cout << "Volume of Box1 : " << volume <length + b.length; box.breadth = this->breadth + b.breadth; box.height = this->height + b.height; return box; } ``` **operate**加上符号可以对符号进行重定义并进行使用(重载 ### 例子中的this->length 去除this部分仍然可以编译运行且运行结果相同 20220214中给value前面加上this->也可以照常运行 > **this 指针的作用** > > this 指针是一个隐含于每一个非静态成员函数中的特殊指针。它指向正在被该成员函数操作的那个对象。当对一个对象调用成员函数时,编译器先将对象的地址赋给 this 指针,然后调用成员函数,每次成员函数存取数据成员时由隐含使用 this 指针。 两次例子刚好是在类内的成员函数内添加或者去除this,所以类内的value和正在操作的this->value等同(? ## 多态 ```c++ #include using namespace std; class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } virtual void area() //int area() { cout << "Parent class area :" <area(); // 存储三角形的地址 shape = &tri; // 调用三角形的求面积函数 area shape->area(); return 0; } //不加virtual的输出结果 //Parent class area : //70 //Parent class area : //50 //添加virtual后 //Rectangle class area : //70 //Triangle class area : //25 ``` > 此时,编译器看的是指针的内容,而不是它的类型。因此,由于 tri 和 rec 类的对象的地址存储在 *shape 中,所以会调用各自的 area() 函数。 > > 正如您所看到的,每个子类都有一个函数 area() 的独立实现。这就是**多态**的一般使用方式。有了多态,您可以有多个不同的类,都带有同一个名称但具有不同实现的函数,函数的参数甚至可以是相同的。 ```c++ virtual int area() = 0; //= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数。 ``` ### C++接口 ```c++ #include using namespace std; // 基类 class Shape { public: // 提供接口框架的纯虚函数 virtual int getArea() = 0; void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // 派生类 class Rectangle: public Shape { public: int getArea() { return (width * height); } }; class Triangle: public Shape { public: int getArea() { return (width * height)/2; } }; int main(void) { Rectangle Rect; Triangle Tri; Rect.setWidth(5); Rect.setHeight(7); // 输出对象的面积 cout << "Total Rectangle area: " << Rect.getArea() << endl; Tri.setWidth(5); Tri.setHeight(7); // 输出对象的面积 cout << "Total Triangle area: " << Tri.getArea() << endl; return 0; } ``` ~~貌似把纯虚函数那一段注释掉结果也是一样的~~ > 设计**抽象类**(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为**接口**使用。如果试图实例化一个抽象类的对象,会导致编译错误。 > > 因此,如果一个 ABC 的子类需要被实例化,则必须实现每个虚函数,这也意味着 C++ 支持使用 ABC 声明接口。如果没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。 > > 可用于实例化对象的类被称为**具体类**。 > > > 实例化是指在面向对象的编程中,把用类创建对象的过程称为实例化。是将一个抽象的概念类,具体到该类实物的过程。实例化过程中一般由类名 对象名 = new 类名(参数1,参数2...参数… > > > > - **中文名:** 实例化 > > > > - **外文名:** instantiate > > > > - **含义:** 用类创建对象的过程 > > > > - **类型:** 编辑过程 > > > > - **格式:** 类名 对象名 = new 类名 > > > > https://baike.baidu.com/item/实例化/3659502 ## 数据抽象和数据封装 与昨天的类访问修饰符相关联 ```c++ #include using namespace std; class Adder{ public: // 构造函数 Adder(int i = 0) { total = i; } // 对外的接口 void addNum(int number) { total += number; } // 对外的接口 int getTotal() { return total; }; private: // 对外隐藏的数据 int total; }; int main( ) { Adder a; a.addNum(10); a.addNum(20); a.addNum(30); cout << "Total " << a.getTotal() < 上面的类把数字相加,并返回总和。公有成员 **addNum** 和 **getTotal** 是对外的接口,用户需要知道它们以便使用类。私有成员 **total** 是对外隐藏的,用户不需要了解它,但它又是类能正常工作所必需的。 ### 友元函数 ```c++ #include using namespace std; class Box { double width; public: friend void printWidth( Box box ); //去除Box后的box可以编译成功 void setWidth( double wid ); }; // 成员函数定义 void Box::setWidth( double wid ) { width = wid; } // 请注意:printWidth() 不是任何类的成员函数 void printWidth( Box box ) { /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */ cout << "Width of box : " << box.width < #include using namespace std; //友元函数 class cFriend { private: int va; int vb; public: cFriend() { va = 0; vb = 0; } cFriend(int a,int b) { va = a; vb = b; } ~cFriend() { cout << "执行结束!!!" << endl; } void set_va(int a) { va = a; } void set_vb(int b) { vb = b; } void disp(); friend void oneline_disp(cFriend dt); }; void cFriend::disp() { cout << "成员函数调用:" << endl; cout << " va = " << va << endl; cout << " vb = " << vb << endl; } void oneline_disp(cFriend dt) { cout << "友元函数调用:" << endl; cout << " va = " << dt.va << endl; cout << " vb = " << dt.vb << endl; } int main() { cFriend data1(4, 5); data1.disp(); oneline_disp(data1); cFriend data2; oneline_disp(data2); return 0; } //https://blog.csdn.net/Mr_Ming_/article/details/78092945?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ELandingCtr%7ERate-1.queryctrv4&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ELandingCtr%7ERate-1.queryctrv4&utm_relevant_index=1 ``` ## 文件读写(就只看个基本格式 ```c++ void open(const char *filename, ios::openmode mode); ``` 关于**openmode** | 模式标志 | 描述 | | :--------- | :----------------------------------------------------------- | | ios::app | 追加模式。所有写入都追加到文件末尾。 | | ios::ate | 文件打开后定位到文件末尾。 | | ios::in | 打开文件用于读取。 | | ios::out | 打开文件用于写入。 | | ios::trunc | 如果该文件已经存在,其内容将在打开文件之前被截断,即把文件长度设为 0。 | 下面是一个实例 ```c++ #include #include using namespace std; int main () { char data[100]; // 以写模式打开文件 ofstream outfile; outfile.open("afile.dat"); cout << "Writing to the file" << endl; cout << "Enter your name: "; cin.getline(data, 100); // 向文件写入用户输入的数据 outfile << data << endl; cout << "Enter your age: "; cin >> data; cin.ignore();//https://baike.baidu.com/item/ignore函数/3404644 // 再次向文件写入用户输入的数据 outfile << data << endl; // 关闭打开的文件 outfile.close(); // 以读模式打开文件 ifstream infile; infile.open("afile.dat"); cout << "Reading from the file" << endl; infile >> data; // 在屏幕上写入数据 cout << data << endl; // 再次从文件读取数据,并显示它 infile >> data; cout << data << endl; // 关闭打开的文件 infile.close(); return 0; } ``` 关于**fstream**定义的三种数据类型 | 数据类型 | 描述 | | :------- | :----------------------------------------------------------- | | ofstream | 该数据类型表示输出文件流,用于创建文件并向文件写入信息。 | | ifstream | 该数据类型表示输入文件流,用于从文件读取信息。 | | fstream | 该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。 |
Comments | NOTHING