美文网首页
C++学习三

C++学习三

作者: 芳心之纵火犯 | 来源:发表于2021-03-30 15:42 被阅读0次

    一、运算符重载

    #include <iostream>
    using namespace std;
    
    class Derry {
    private:
        int x,y;
    
    public:
        Derry() {
    
        }
    
        // 系统C++源码,大量使用此方式 :x(x), y(y)
        Derry(int x, int y) :x(x), y(y) {}
    
        void setX(int x) {
            this->x = x;
        }
        void setY(int y) {
            this->y = y;
        }
        int getX() {
            // this->x  -9; 系统怕你在函数里面 修改了
            return this->x;
        }
        int getY() {
            return this->y;
        }
    
        // +号,运算符重载  类内重载
        /*Derry operator + (Derry derry1) {
            // this指针 指向当前对象,所以只需要一个
            int x = this->x + derry1.getX();
            int y = this->y + derry1.getY();
            return Derry(x, y);
        }*/
    
        // 系统是这样写的  常量引用:不允许修改,只读模式
        // & 性能的提高,如果没有&  运行+ 构建新的副本,会浪费性能
        // 如果增加了& 引用是给这块内存空间取一个别名而已
        Derry operator + (const Derry& derry1) {
            //int x = this->x + derry1.getX(); //这样是不行的,虽然是get函数,但是系统怕你在函数里面有修改值
            int x = this->x + derry1.x; // 我在类的里面,是可以拿私有成员的
            int y = this->y + derry1.y; 
            return Derry(x, y);
        }
    
        // 运算符- 重载
        Derry operator - (const Derry & derry1) {
            int x = this->x - derry1.x;
            int y = this->y - derry1.y;
            return Derry(x, y);
        }
    
        // 对象++ 运算符 重载
        void operator ++() { //  ++对象
            this->x = this->x + 1;
            this->y = this->y + 1;
        }
        void operator ++ (int) { // 对象++
            this->x = this->x + 1;
            this->y = this->y + 1;
        }
    
        // istream 输入 系统的
        // ostream 输出 系统的
        // 输出 运算符重载 复杂 涉及到规则  重载<<
        friend void operator << (ostream & _START, Derry derry1) {
            // 输出换行:<< endl;
            _START << " 单 哥开始输出了 " << derry1.x << " ! " << derry1.y << " 哥结束了 " << endl;
        }
    
        // 多个的  ostream 输出 系统的
        // 输出 运算符重载 复杂 涉及到规则  重载 >>
        /*friend ostream & operator >> (ostream & _START, const Derry & derry1) {
            _START << " 多 哥开始输出了 " << derry1.x << " ! " << derry1.y << " 哥结束了 " << endl;
            return _START;
    
            // RxJava 链式调用  .操作符.操作符.操作符 你每次都是返回this  一个思路
        }*/
    
        // istream 输入 系统的
        friend istream & operator >> (istream & _START, Derry & derry) {
            // 接收用户的输入,把输入的信息,给x
    
            // _START >> derry.x;
            // _START >> derry.y;
    
            // 可读性不好,简化了
            _START >> derry.x >> derry.y;
    
            return _START;
        }
    };
    // 在真实开发过程中,基本上都是写在类的里面的,因为外部是不能获取内部的私有成员的
    // 把+重载 运算符重载
    //类外运算符重载
    Derry operator + (Derry derry1, Derry derry2) {
        int x = derry1.getX() + derry2.getX();
        int y = derry1.getY() + derry2.getY();
    
        Derry res(x, y);
        return res;
    }
    int main() {
        Derry derry1(1000, 2000);
        Derry derry2(3000, 4000);
    
        // Derry result = derry1 + derry2;
    
        // Derry result = derry2 - derry1;
    
        Derry result(1, 2);
        result++;
        ++result;
    
        cout << result.getX() << " , " << result.getY() << endl;
    
        cout << endl; // 系统的换行
    
        // 自定义的,系统没有考虑 你要输出 derry1对象,怎么办? 我们需要自定义 <<
        cout << derry1; // 单个的
    
        // cout >> derry1 >> derry1 >> derry1 >> derry1; // 多个的
    
        cout << endl; // 系统的换行
    
        // cout 输出的 C++
        // cin 输入的 C++
    
        Derry res;
        cin >> res; // >> 是我们自己重载的哦
        cout << "你输入的是:" << res.getX() << endl;
        cout << "你输入的是:" << res.getY() << endl;
    
        return 0;
    }
    

    二、继承

    1、基本
    #include <iostream>
    
    using namespace std;
    
    class Person {
    public:
        char *name;
        int age;
    
    public:
        Person(char *name, int age) : name(name) {
            this->age = age;
            cout << "Person 构造函数" << endl;
        }
    
        void print() {
            cout << this->name << " , " << this->age << endl;
        }
    };
    
    // 1.默认是 隐式代码: : private Person
    // 2.私有继承:在子类里面是可以访问父类的成员,但是在类的外面不行
    // 3.必须公开继承,才可以访问父类的成员
    class Student : public Person {
    
    // 类 默认是私有,注意下
    private:
        char * course;
    
    public:
        // :父类 , 给自己子类成员初始化
        Student(char * name, int age, char* course) : Person(name, age) , course(course) {
            cout << "Student 构造函数" << endl;
        }
    
        void test() {
            cout << name << endl;
            cout << age << endl;
            print();
        }
    };
    
    int main() {
        Student stu("李元霸", 99, "C++");
    
        // 公开继承,才可以拿父类的成员
        stu.name = "李四";
    
        return 0;
    }
    
    2、多继承、二义性
    #include <iostream>
    using namespace std;
    class BaseActivity1 {
    public:
        void onCreate() {
            cout << "BaseActivity1 onCreate" << endl;
        }
        void show() {
            cout << "BaseActivity1 show" << endl;
        }
    };
    
    class BaseActivity2 {
    public:
        void onCreate() {
            cout << "BaseActivity2 onCreate" << endl;
        }
        void show() {
            cout << "BaseActivity2 show" << endl;
        }
    };
    
    class BaseActivity3 {
    public:
        void onCreate() {
            cout << "BaseActivity3 onCreate" << endl;
        }
        void show() {
            cout << "BaseActivity3 show" << endl;
        }
    };
    
    // 子类 继承 三个父类
    class MainActivity1 : public BaseActivity1, public BaseActivity2, public BaseActivity3 {
    public:
        void onCreate() {
            cout << "MainActivity1 onCreate" << endl;
        }
    
        // 解决方案二: 子类上 重写父类的show函数
        void show() {
            cout << "MainActivity1 show" << endl;
        }
    
    };
    
    int main() {
        // 这个是优先寻找子类的函数,因为特别明确,没有问题,还没有产生歧义(二义性)
        MainActivity1 mainActivity1; // 子类
        mainActivity1.onCreate(); 
    
        // error: request for member 'show' is ambiguous
        // 不明确,二义性,歧义
        // mainActivity1.show();
    
        // 解决方案一: 明确指定父类 ::
        mainActivity1.BaseActivity3::show();
        mainActivity1.BaseActivity2::show();
        mainActivity1.BaseActivity1::show();
    
        // 解决方案二: 子类上 重写父类的show函数
        mainActivity1.show();
    
        return 0;
    }
    
    3、属性二义性
    #include <iostream>
    using namespace std;
    // 祖父类
    class Object {
    public:
        int number;
    };
    
    // 父类1
    class BaseActivity1 : public Object {
    };
    // 父类2
    class BaseActivity2 : public Object {
    };
    // 子类
    class Son : public BaseActivity1, public BaseActivity2 {
        // 第二种解决方案: 在类中定义同名成员,覆盖掉父类的相关成员
    public:
        int number;
    };
    int main() {
        Son son;
        //  二义性 歧义
        // son.number = 2000;
    
        // 第一种解决方案: :: 明确指定
        son.BaseActivity1::number  = 1000;
        son.BaseActivity2::number  = 1000;
    
        // 第二种解决方案: 在类中定义同名成员,覆盖掉父类的相关成员
        son.number = 3000;
        // 第三种解决方案: 【虚基类】 属于 虚继承的范畴
        return 0;
    }
    
    4、虚基类(虚继承)
    #include <iostream>
    using namespace std;
    // 祖父类
    class Object{
    public:
        int number;
        void show() {
            cout << "Object show run..." << endl;
        }
    };
    // 父类1
    class BaseActivity1 : virtual public Object {
    // public:int number; // 人为制作二义性  
    };
    // 父类2
    class BaseActivity2 : virtual public Object {
    // public:int number;
    };
    
    // 子类
    class Son : public BaseActivity1, public BaseActivity2 {
    };
    
    int main() {
        Object object;
        BaseActivity1 baseActivity1;
        BaseActivity2 baseActivity2;
        Son son;
    
        object.number = 100;
        baseActivity1.number = 200;
        baseActivity2.number = 300;
        son.number = 400;
    
        object.show();
        baseActivity1.show();
        baseActivity2.show();
        son.show();
        return 0;
    }
    
    二义性.png

    三、多态(虚函数)

    // 多态(虚函数)。   动态多态(程序的角度上:程序在运行期间才能确定调用哪个类的函数 == 动态多态的范畴)
    // Java语言默认支持多态
    // C++默认关闭多态,怎么开启多态? 虚函数  在父类上给函数增加 virtual关键字
    // 请问什么是多态? 父类的引用指向之类的对象,同一个方法有不同的实现,重写(动态多态)和   重载(静态多态)
    #include <iostream>
    using namespace std;
    class BaseActivity {
    public:
         virtual void onStart() { //虚函数
            cout << "BaseActivity onStart" << endl;
        }
    };
    
    class HomeActivity : public BaseActivity {
    public:
        void onStart() { // 重写父类的函数
            cout << "HomeActivity onStart" << endl;
        }
    };
    
    class LoginActivity : public BaseActivity {
    public:
        void onStart() { // 重写父类的函数
            cout << "LoginActivity onStart" << endl;
        }
    };
    
    void startToActivity(BaseActivity * baseActivity) {
        baseActivity->onStart();
    }
    
    int main() {
        // TODO 第一版本 如果不是虚函数打印的都是BaseActivity
        HomeActivity *homeActivity = new HomeActivity();
        LoginActivity *loginActivity = new LoginActivity();
    
        startToActivity(homeActivity);
        startToActivity(loginActivity);
    
        if (homeActivity && loginActivity) delete homeActivity; delete loginActivity;
    
        cout << endl;
    
        // TODO 第二个版本
        BaseActivity * activity1 = new HomeActivity();
        BaseActivity * activity2 = new LoginActivity();
        startToActivity(activity1);
        startToActivity(activity2);
        return 0;
    }
    
    
    // 静态多态 (编译期已经决定,调用哪个函数了,这个就属于静态多态的范畴)  重载(静态多态)
    #include <iostream>
    using namespace std;
    void add(int number1, int number2) {
        cout << number1 + number2 << endl;
    }
    void add(float number1, float number2) {
        cout << number1 + number2 << endl;
    }
    void add(double number1, double number2) {
        cout << number1 + number2 << endl;
    }
    int main() {
        add(10000, 10000);
        add(1.9f, 2.8f);
        add(545.4, 654.54);
        return 0;
    }
    

    四、纯虚函数

    // 纯虚函数(Java版抽象类)
    // C++纯虚函数(C++没有抽象类)  相当于 Java的抽象类  为了更好理解
    
    #include <iostream>
    using namespace std;
    
    // 抽象类/纯虚函数: 分为:1.普通函数, 2.抽象函数/纯虚函数
    class BaseActivity {
    private:
        void setContentView(string layoutResID) {
            cout << "XmlResourceParser解析布局文件信息... 反射" << endl;
        }
    
    public:
        // 1.普通函数
        void onCreate() {
            setContentView(getLayoutID());
            initView();
            initData();
            initListener();
        }
    
        // 纯虚函数是必须继承的(如果子类没有重写纯虚函数,子类就是抽象类), 虚函数是不是不必须的
    
        // 2.抽象函数/纯虚函数
        // virtual string getLayoutID(); // 虚函数
        virtual string getLayoutID() = 0; // 纯虚函数
        virtual void initView() = 0;
        virtual void initData() = 0;
        virtual void initListener() = 0;
    };
    
    // 子类 MainActivity
    class MainActivity : public BaseActivity { // MainActivity如果没有重新父类的纯虚函数,自己就相当于 抽象类了
        string getLayoutID() {
            return "R.layout.activity_main";
        }
    
        void initView()  {
        }
    
        void initData() {
        }
    
        void initListener() { 
        }
    };
    

    五、全纯虚函数

    // 虚函数  纯虚函数 全纯虚函数(C++没有接口) 等价于  全纯虚函数(Java版接口)。
    #include <iostream>
    using namespace std;
    class Student {
        int _id;
        string name;
        int age;
    };
    
    // 此类所有的函数 ,都是纯虚函数,就相当于 Java的接口了
    class ISudent_DB {
        virtual void insertStudent(Student student) = 0;
        virtual void deleteStudent(int _id) = 0;
        virtual void updateStudent(int _id, Student student) = 0;
        virtual Student queryByStudent(Student student) = 0;
    };
    
    // Java的实现类
    class Student_DBImpl1 : public ISudent_DB {
    public:
        void insertStudent(Student student) {
            // 插入操作,省略代码...
        }
    
        void deleteStudent(int _id) {
            // 删除操作,省略代码...
        }
    
        void updateStudent(int _id, Student student) {
            // 更新操作,省略代码...
        }
    
        Student queryByStudent(Student student) {
            // 查询操作,省略代码...
        }
    };
    int main() {
        Student_DBImpl1 studentDbImpl1;
        Student_DBImpl2 studentDbImpl2;
        Student_DBImpl3 studentDbImpl3;
    
        cout << "Success" << endl;
    
        return 0;
    }
    
    登录实例:
    // 回调  Java的登录 简单的 接口
    #include <iostream>
    using namespace std;
    // 登录成功的Bean
    class SuccessBean {
    public:
        string username;
        string userpwd;
    
        SuccessBean(string username, string userpwd)
        :username(username), userpwd(userpwd) {}
    };
    
    // 登录响应的接口  成功,错误
    class ILoginResponse {
    public:
        // 登录成功
        virtual void loginSuccess(int code, string message, SuccessBean successBean) = 0;
    
        // 登录失败
        virtual void loginError(int code, string message) = 0;
    };
    
    // 登录的API动作
    void loginAction(string name, string pwd, ILoginResponse & loginResponse) {
        if (name.empty() || pwd.empty()) {
            cout << "用户名或密码为空!" << endl;
            return;
        }
    
        if ("Derry" == name && "123" == pwd) {
            loginResponse.loginSuccess(200, "登录成功", SuccessBean(name, "恭喜你进入"));
        } else {
            loginResponse.loginError(404, "登录错误,用户名或密码错误...");
        }
    }
    
    // 写一个实现类,继承接口
    // 接口实现类
    class ILoginResponseImpl : public ILoginResponse {
    public:
        // 登录成功
        void loginSuccess(int code, string message, SuccessBean successBean) {
            cout << "恭喜登录成功 " << "code:" << code << " message:" << message
            << "successBean:" << successBean.username << "," << successBean.userpwd << endl;
        }
    
        // 登录失败
        void loginError(int code, string message) {
            cout << " 登录失败 " << "code:" << code << " message:" << message << endl;
        }
    };
    
    int main() {
    
        // 做实验
        // Allocating an object of abstract class type 'ILoginResponse'
        // 正在分配抽象类型为ILoginResponse的对象  不能被实例化
        // 纠结:为什么不可以
        // 1.他不是Java的接口,C++也没有接口,他只是像接口而已。
        // 2.他也不是抽象类,C++也没有抽象类,他只是像抽象类而已。
        // 3.他是纯虚函数的类,此类决定不准你实例化  无论堆区 还是栈区
        /*new ILoginResponse() {
            // 登录成功
            void loginSuccess(int code, string message, SuccessBean successBean) {
    
            }
    
            // 登录失败
            void loginError(int code, string message) {
    
            }
        }*/
    
        string username;
        cout << "请输入用户名.." << endl;
        cin >> username;
    
        string userpwd;
        cout << "请输入密码.." << endl;
        cin >> userpwd;
    
        ILoginResponseImpl iLoginResponse;
        loginAction(username, userpwd, iLoginResponse);
    
        return 0;
    }
    

    六、模板函数

    // 模版函数(Java版泛型)。  C++没有泛型 C++的模板函数 非常类似于 Java的泛型
    #include <iostream>
    using namespace std;
    // 加分合集  int double float ... 你都要考虑,你是不是要定义很多的 函数
    /*void addAction(int n1, int n2) {
        cout << "addAction(int n1, int n2):" << n1 + n1 << endl;
    }
    void addAction(float n1, float n2) {
        cout << "addAction(int n1, int n2):" << n1 + n1 << endl;
    }
    void addAction(double n1, double n2) {
        cout << "addAction(int n1, int n2):" << n1 + n1 << endl;
    }*/
    // 模板函数  == Java的泛型解决此问题
    template <typename TT>
    void addAction(TT n1, TT n2) {
        cout << "模板函数:" << n1 + n2 << endl;
    }
    int main() {
        addAction(1, 2);
        addAction(10.2f, 20.3f);
        addAction(545.34, 324.3);
        addAction<string>("AAA", "BBB");
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:C++学习三

          本文链接:https://www.haomeiwen.com/subject/fowfhltx.html