c++教程2021-6-18学习笔记

/**
 * 继承:公共继承/保护继承/私有继承
 * class 子类:继承方式  父类
 */

//public 继承,除了父类私有,其他的都直接原有权限拿来。
//protected 继承,除了父类私有,其他权限都是保护拿来。
//private 继承,除了父类私有,其他的都是私有拿来。


class BasePage {
public:
    void baseInfo() {
        cout << "公共部分" << endl;
    }
    int m_Pub;
protected:
    int m_pro;
private:
    int m_pri;
};

class Son1 : public BasePage {
public:
    Son1() {
        m_Pub = 100;//public 继承过来。
        m_pro = 100;//protected 继承过来。
//        m_pri = 100;//不能访问
    }
    int m_son1;
};

class Son2 : protected BasePage {
public:
    Son2() {
        m_Pub = 100;//protected 继承过来。
        m_pro = 100;//protected 继承过来。
//       m_pri = 100;//不能访问
    }
};

class Son3 : private BasePage {
public:
    Son3() {
        m_Pub = 100;//private 继承过来。
        m_pro = 100;//private 继承过来。
//       m_pri = 100;//不能访问
    }
};


class Java : public BasePage {
public:
    void content() {
        cout << "Java特有部分" << endl;
    }
};

class CPP : public BasePage {
public:
    void content() {
        cout << "CPP特有部分" << endl;
    }
};

int main() {

    Java java;
    java.baseInfo();
    java.content();
    cout << "__________________" << endl;
    CPP cpp;
    cpp.baseInfo();
    cpp.content();

    Son1 son1;
    son1.m_Pub;//这里只能使用public 部分。
    Son2 son2;//在类外都无法访问。因为是protected
    Son3 son3;//在类外都无法访问。因为是private

    cout << sizeof (son1)<<endl;//结果16,说明所有的非静态属性继承过来的内容。属于子类。包含私有。只是私有的隐藏起来。
    cout << sizeof (son2)<<endl;//结果12,说明所有的非静态属性继承过来的内容。属于子类。包含私有。只是私有隐藏起来。
    return 0;
}



//继承中构造和析构函数的执行顺序。
//构造的时候,先有父类构造,析构与之相反。
//继承中同名的成员处理。

class Base {
public:
    Base() {
        m_A = 40;
    }

    int m_A;

    void func(int a) {
        cout << "Base (int a)func" << endl;
    }

    void func() {
        cout << "Base func" << endl;
    }
};

class Son : public Base {
public:
    Son() {
        m_A = 10;
    }

    int m_A;

    void func() {
        cout << "Son func" << endl;
    }
};

int main() {
    Son son;
    cout << "子类的值:" << son.m_A << endl;
    Base base;
    cout << "父类的值:" << base.m_A << endl;
    cout << "父类的值:" << Base().m_A << endl;
    //如果想通过子类对象,获取到父类的成员属性。
    cout << "父类的值:" << son.Base::m_A << endl;
    son.func();
    //下面编译报错。因为如果子类实现了同名的成员函数,那么就会隐藏父类所有的同名函数的实现。
    //如果想调用父类的函数,那么只有加作用域。
//    son.func(100);
    son.Base::func(100);
    return 0;
}




//继承中的静态成员处理,下面是成员属性。成员函数也是如此。。
//多重继承。class 子类:继承方式 父类1,继承方式 父类2.  如果出现同名属性,则用作用域进行区分。

class Base{
public:
    static int m_A;
};
int Base::m_A = 200; //对父类的静态成员进行初始化。

class Son : public Base{
public:
    static int m_A;
};
int Son::m_A = 100;//对子类的静态成员属性进行初始化。


int main(){
    Son son;
    cout << "子类"<<son.m_A<<endl;
    cout << "父类"<<son.Base::m_A<<endl;
    cout << "-----------------"<<endl;
    cout << "子类"<<Son::m_A<<endl;
    cout << "父类"<<Base::m_A<<endl;
    cout << "父类"<<Son::Base::m_A<<endl;
    return 0;
}


//菱形继承,也称为多继承。会copy两份数据。造成浪费。
//解决这一问题,通过virtual 关键字进行继承。也称为虚继承。
//如果不加virtual那么就会继承两份数据过来。
class Animal{//动物
public :
    int m_Age;
};
class Sheep:virtual public Animal{//羊
public:
    Sheep(){
        m_Age = 100;
    }
};
class Camel:virtual public Animal{//驼
public:
    Camel(){
        m_Age = 200;
    }
};

class SheepCamel:public Sheep,public Camel{};//羊驼

int main(){
    SheepCamel sheepCamel;
    cout << sheepCamel.m_Age<<endl;
    cout << sheepCamel.Sheep::m_Age<<endl;
    cout << sheepCamel.Camel::m_Age<<endl;
    return 0;
}


/**
 * 动态多态:
 * 1.继承
 * 2.子类要重写父类的虚函数。(返回值,函数名,参数列表完全相同)
 * 3.父类的指针或者引用指向子类的对象。
 */

//动物基类
class Animal {
public:
    virtual void speak() { //如果这里不是虚函数,那么就是前绑定,不会形成多态。绑定为基类的方法执行。如果声明为virtual,形成多态的必要条件之一。
        cout << "动物在说话" << endl;
    }
};

//猫类
class Cat : public Animal {
public:
    void speak() {
        cout << "小猫在说话" << endl;
    }
};

// 这里有一个说话的方法
void doSpeak(Animal &a) {
    a.speak();
}

void test() {
    Cat cat;
    doSpeak(cat);
}
void test01() {
    //如果Animal 中没有virtual,那么就是一个空类,sizeof(Animal)=1
    //如果Animal 中有virtual,那么就是一个空类,sizeof(Animal)=8,多了地址(指针)
    cout << sizeof(Animal) << endl;
}

int main() {
    test();
    test01();
    return 0;
}



/**
 *普通写法和多态写法实现计算器
 */
//这里涉及到一个开闭原则:对扩展开放,对修改关闭。

//传统写法
class Caculator {
public:
    Caculator(int a, int b) : m_Num1(a), m_Num2(b) {

    }

    int getResult(string oper) {
        if ("+" == oper) {
            return m_Num1 + m_Num2;
        } else if ("-" == oper) {
            return m_Num1 - m_Num2;
        } else if ("*" == oper) {
            return m_Num1 * m_Num2;
        }
    }

private :
    int m_Num1;
    int m_Num2;
};

class AbstractCaculator {
public:
    virtual int getResult() {

    }

    int m_Num1;
    int m_Num2;
};

//+法
class AddCaculator : public AbstractCaculator {
public:
    int getResult() {
        return m_Num1 + m_Num2;
    }
};

//-法
class SubCaculator : public AbstractCaculator {
public:
    int getResult() {
        return m_Num1 - m_Num2;
    }
};

//传统形式的计算器写法测试
void test() {
    Caculator caculator(2, 3);
    cout << caculator.getResult("+") << endl;
}

//多态实现测试
void test01() {
    AbstractCaculator *abstractCaculator = new AddCaculator(); //加法
    abstractCaculator->m_Num1 = 10;
    abstractCaculator->m_Num2 = 5;
    int ret = abstractCaculator->getResult();
    cout << ret << endl;
    delete abstractCaculator;

    abstractCaculator = new SubCaculator(); //减法
    abstractCaculator->m_Num1 = 10;
    abstractCaculator->m_Num2 = 5;
    ret = abstractCaculator->getResult();
    cout << ret << endl;
    if (abstractCaculator != NULL) {
        delete abstractCaculator;
        abstractCaculator = NULL;
    }
}

int main() {
    //test();
    test01();
    return 0;
}


/**
 * 抽象类和纯虚函数:
 * 只要有一个纯虚函数的类就是抽象函数。
 * 抽象类无法实例化对象,子类必须重写纯虚函数,否则也是抽象类。
 * 纯虚函数语法:virtual 返回值 函数名() = 0;
 */

class Base{//这是一个抽象类,不能被实例化。继承该类的子类需要实现纯虚函数。否则也是抽象函数。
public:
    virtual void func() = 0;//这是一个纯虚函数。
};


class Son:public Base{
public:
    void func(){//子类需要实现这个纯虚函数。
        cout<<"Son func exec"<<endl;
    }
};

int main(){
//    Base base;//编译报错,因为抽象函数不能被实例化
    Son son;
    son.func();
    return 0;
}



/**
 *虚析构函数 和纯析构函数
 */
 //适用场景:如果子类的属性开辟在堆中,那么父类无法释放子类中的内存。
//都是用来解决子类属性申请在堆空间。无法释放内存的问题。

class Animal{
public:
    virtual  void speak() = 0;
//    virtual ~Animal() = 0;
    virtual ~Animal(){
        cout << "动物析构函数函数被调用。"<<endl;
    }
};

//Animal::~Animal() {
//    cout << "动物析构函数函数被调用。"<<endl;
//}

class Cat:public Animal{
public:
    Cat(string name){
        cout << "猫的构造函数函数被调用。"<<endl;
        m_Name = new string(name);
    }
    void speak(){
        cout << "小猫在叫"<<endl;
    }
    ~Cat(){
        cout << "猫的析构函数函数被调用。"<<endl;
        if (m_Name != NULL){
            delete m_Name;
            m_Name = NULL;
        }
    }
    string *m_Name;
};

int main(){
    Animal  *animal = new Cat("Tom");
    animal->speak();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值