输入输出流重载说明:std::ostream operator<<(std::ostream os, const Vector v)
首先这是一个函数函数名字是operator函数的输出类型是std::ostream输入类型是std::ostream const Vector v相当于(std::cout v)的重载后的输出可以是std::cout以便格式化输出Vector类型之后还能够继续链式输出其他内容。// 输入输出流重载#include iostreamstruct Vector {double x, y;};// 输出流重载std::ostream operator(std::ostream os, const Vector v) {os ( v.x , v.y );return os;}// 输入流重载std::istream operator(std::istream is, Vector v) {is v.x v.y;return is;}int main() {Vector v1, v2;// 输入std::cout Enter Vector 1 (x y): ;std::cin v1; // 例如输入: 1.0 2.0std::cout Enter Vector 2 (x y): ;std::cin v2; // 例如输入: 3.0 4.0// 输出std::cout Vector 1: v1 std::endl; // 输出: Vector 1: (1.0, 2.0)std::cout Vector 2: v2 std::endl; // 输出: Vector 2: (3.0, 4.0)return 0;}2.2.3 函数运算符重载class Adder {public:int operator()(int a, int b) {return a b;}};Adder add;int result add(3, 4); // 看起来像函数调用实际是调用 operator()// 匿名函数对象std::cout Adder()(3, 4) std::endl;2.3 继承概念继承允许我们创建一个新类派生类这个新类会继承一个基类的属性和行为实现代码的重用和类之间的层次关系。核心思想提取出一类物品的公共属性和行为。比如猫狗鸟等都属于动物动物就可以作为父类。继承是多态的基础。子类可以对父类的成员函数进行重写。虚函数的重写是为了实现多态。2.3.1 语法格式// class Manager : public Employee {#include iostream#include string// 基类员工class Employee {public:// 基类的构造函数Employee(std::string name, int id, double salary): m_name(name),m_id(id),m_salary(salary) {}// 基类的成员函数void work() {std::cout m_name (ID: m_id ) is working. std::endl;}void showInfo() {std::cout Name: m_name , ID: m_id , Salary: m_salary std::endl;}protected: // protected成员在基类和派生类中都可以访问std::string m_name;int m_id;double m_salary;};// 派生类经理公有继承自Employeeclass Manager : public Employee {public:// 派生类的构造函数需要调用基类的构造函数来初始化基类部分Manager(std::string name, int id, double salary, double bonus): Employee(name, id, salary),m_bonus(bonus) {} // 初始化列表// 派生类新增的成员函数void manageTeam() {std::cout m_name is managing the team. std::endl;}// 派生类可以重写覆盖基类的函数void showInfo() {// 先调用基类的showInfo()显示共同信息Employee::showInfo(); // 使用作用域解析符调用基类版本// 再显示派生类特有的信息std::cout Bonus: m_bonus std::endl;}private:// 派生类新增的成员变量double m_bonus;};int main() {Employee emp(Alice, 1001, 8000.0);emp.work(); // Alice (ID: 1001) is working.emp.showInfo(); // Name: Alice, ID: 1001, Salary: 8000std::cout --------------------- std::endl;Manager mgr(Bob, 2001, 15000.0, 5000.0);mgr.work(); // Bob (ID: 2001) is working. (继承自Employee)mgr.manageTeam(); // Bob is managing the team. (Manager自己的)mgr.showInfo(); // 调用的是Manager重写后的版本// Name: Bob, ID: 2001, Salary: 15000// Bonus: 5000return 0;}2.3.2 继承方式有公有保护私有三种方式。继承方式决定了基类中的成员在派生类中的访问权限。继承方式是为了限制“外部”对“基类部分”的访问而不是限制派生类内部对基类成员的访问。总之派生类对基类的访问权限取决于基类和继承方式的最小权限。只有两个都是public时外部才能访问。无论哪种继承方式基类的private成员永远无法被派生类直接访问。它们虽然被继承了存在于派生类对象中但对派生类来说是“不可见”的。派生类只能通过基类提供的public或protected接口来间接访问它们。2.3.3 继承中的构造/析构函数构造函数和析构函数不能被继承但是在创建派生类对象时基类的构造函数会自动被调用。构造函数的调用顺序先调用基类的构造函数再调用派生类自己的构造函数。// Manager的构造函数Manager(std::string name, int id, double salary, double bonus): Employee(name, id, salary), // 在初始化列表中调用基类构造函数m_bonus(bonus) { // 初始化派生类自己的成员// 函数体}析构函数的调用顺序相反。2.3.4 继承的内存布局派生类对象包含了基类的所有非静态成员变量以及派生类自己新增的非静态成员变量。这些成员在内存中通常是连续存放的基类的部分在前派生类的部分在后。成员函数包括虚函数并不存储在每个对象中。它们存储在代码段。每个对象中只存储一个指向虚函数表的指针如果类有虚函数通过这个指针来找到正确的函数版本。2.3.5 继承中的静态成员无论继承出多少个派生类整个继承体系中只有一个静态成员的实例。静态成员变量被所有基类和派生类的对象共享。静态成员函数没有this指针只能访问静态成员。它同样被继承但无法被重写为虚函数因为虚函数依赖于this指针和虚表。静态成员函数可以通过基类或者派生类的作用域来访问。