C++学习笔记 入门篇-5

前言

本系列内容为程序媛学习C++时做的笔记。以代码为主,并备注了打印结果以及详尽的解释注释。希望对你有所帮助。在这里插入图片描述

对象继承

#include <iostream>
using namespace std;

class Animal {
private:
    char *name;
public:
    Animal(char *name) { this->name = name; }

    void printName() {
        cout << name << endl;
    }
};

//这样写:   class Pig : Animal
//默认继承是private Animal,子类在类外面不能调用printName(),否则编译报错
//要加public继承,才能在pig外面调用,否则(私有继承)只能在子类里面访问父类成员
class Pig : public Animal {
private:
    int age;
public:
    Pig() : Animal("小花") {}

    Pig(char *name) : Animal(name) {}

    //继承父类的同时,给自己的成员age初始化
    Pig(char *name, int age) : Animal(name), age(age) {}

    void printNameAge() {
        //不是public Animal,也可以调用printName();
        printName();

        cout << age << endl;
    }
};

int main() {
    Pig pig("小黑", 111);
    pig.printName();//如果不是public Animal,该行编译报错  //输出小黑
    pig.printNameAge();//小黑  111
    return 0;
}

对象属性初始化:

class Course {
private:
    string course;
public:
    Course(string course) : course(course) {}
};

class Person {
private:
    string name;

public:
    Person(string name) : name(name) {}
};

class Student : public Person {
private:
    Course course;
public:
    Student() : Person("张三"), course("语文") {}//第一种初始化方式

    Student(Course cou) : Person("李四"), course(cou) {}//第2种初始化方式
};

多继承的二义性问题

C++是有多继承的
Java语言不允许多继承,多继承有歧义,如果Java语言多继承 就会导致代码不健壮,(二义性)

解决1:

#include <iostream>
using namespace std;

class Base1 {
public:
    void onCreate() {};

    void onStart() {};
};

class Base2 {
public:
    void onCreate() {};

    void onStart() {};
};

class Activity : public Base1, public Base2 {
public:
//没有重写onCreate()方法

    void onStart() {};
};

int main() {
    Activity ac;

//ac.onCreate();//不知道调用哪个父类的方法,所以有歧义,编译报错,可以如下调用:
    ac.Base2::onCreate();//明确指定调用谁的

// 这个是优先寻找子类的函数,因为特别明确,没有问题,还没有产生歧义(二义性)
    ac.onStart();
    return 0;
}

二义性原因:
Base1和Base2都有onCreate方法
解决:
::指定说明调用谁的方法 Base2::
或者子类直接重写方法。 void onStart() {};

解决2:

#include <iostream>
using namespace std;

class Obj {
public:
    int number;
};

class Base1 : virtual public Obj {

};

class Base2 : virtual public Obj {

};

class Use : public Base1, public Base2 {
};

int main() {
    Obj obj;
    Base1 base1;
    Base2 base2;
    Use use;

    obj.number;
    base1.number;
    base2.number;
    use.number;
    return 0;
}

在这里插入图片描述

二义性原因:
Object有number,父类1和2都给继承了过来。Son在用的时候就不知道用哪个父类的了。
解决:
虚继承,让number只存在Obj里面,不给继承到Base1/Base2里。调用的时候就明确知道调用的都是Obj里面的。

运算符重载

#include <iostream>

using namespace std;

class AddXY {
public:
    int x, y;

    // 系统C++源码,大量使用此方式 :x(x), y(y)
    AddXY(int x, int y) : x(x), y(y) {}
};

// 把+重载 运算符重载
// 在真实开发过程中,基本上都是写在类的里面的? 答:外部是不能获取内部的私有成员的
AddXY operator+(AddXY a, AddXY b) {
    return AddXY(a.x + b.x, a.y + b.y);
}

int main() {
    AddXY a(1, 2);
    AddXY b(3, 4);

    AddXY c = a + b;
    cout << c.x << endl;//4
    cout << c.y << endl;//6
    return 0;
}

类里面运算符重载

举例1:

class AddXY {
public:
    //写在里面省一个入参
    // 系统是这样写的  常量引用:不允许修改,只读模式
    // const 关键字的解释
    // & 性能的提高,如果没有&  运行+ 构建新的副本,会浪费性能
    // 如果增加了& 引用是给这块内存空间取一个别名而已
    AddXY operator+(const AddXY &b) {
        return AddXY(this->x + b.x, this->y + b.y);//b.y=4
    }
};

调用:

a+b;//输出同上

举例2:

class AddXY {
public:
    void operator++(int) {//对象++   (++对象没有入参int)
        this->x = this->x + 1;
        this->y = this->y + 1;
    }
};

调用:

AddXY a(1, 2);
a++;
cout << a.x << endl;//2
cout << a.y << endl;//3

举例3:

重载系统的输入输出运算符。

class Sun {
public:
    int x, y;

    Sun() {}

    Sun(int x, int y) : x(x), y(y) {}

    // istream 输入 系统的 >>
    // ostream 输出 系统的 <<
    friend ostream &operator>>(ostream &_START, const Sun &sun) {
        _START << "重载>>运算符" << endl;
        return _START;
    }

    friend istream &operator>>(istream &_START, Sun &sun) {//没有const,有const的sun.x就不给赋值了
        _START >> sun.x;//第一次输入的值给x
        _START >> sun.y;//第二次输入的值给y
        //_START >> derry.x >> derry.y;//简化写法
    }
};

调用:

Sun sun;
cout >> sun >> sun >> sun;//调用我们重载的
//输出
//重载>>运算符
//重载>>运算符
//重载>>运算符

调用:

Sun sun;
cin >> sun;//调用我们重载的
cout << sun.x << "~" << sun.y << endl;

//	11(回车)
//	22(回车)
//	11~22

重载括号运算符

#include <iostream>
using namespace std;

class ArraySun {
private:
    int arr[10];
public:
    void set(int index, int value) {
        arr[index] = value; // []目前不是我的
    }

    int operator[](int index) {//自定义[]
        cout << "第" << index << "个元素是:" << this->arr[index] << endl;//调用系统的[]
        return this->arr[index];
    }
};

int main() {
    ArraySun arrs;
    arrs.set(0, 111);
    arrs.set(1, 222);
    arrs.set(2, 333);
    //调用自定义的[]
    arrs[2] ; //第2个元素是:333
  
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值