c语言中的类和继承复习

  实现一个简单的猫咪🐈类:

  c1.h:

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Cat{
public:
    Cat(int intialAge);
    ~Cat();
    int getAge() const {
        return itsAge;
    }
    void setAge(int age) {
        itsAge = age;
    }
    void Meow() const {
        cout << "Meow \n";
    }
private:
    int itsAge;
};
复制代码

  c1.cpp

运行下面代码

复制代码
#include "c1.h"
Cat::Cat(int initialAge) {
    itsAge = initialAge;
}
Cat::~Cat() {}
int main() {
    Cat c(5);
    c.Meow();
    c.setAge(8);
    cout << "now age is " << c.getAge() << endl;
    return 0;
}
复制代码

   类的继承和派生:

  实现一个父类Mammal, 让Dog继承这个父类:

运行下面代码

复制代码
#include <iostream>
using namespace std;
enum BREED{GOLDEN, DANDIE, LAB};
class Mammal{
public:
    Mammal(){};
    ~Mammal(){};
    //访问器和设置器;
    int getAge() const {
        return itsAge;
    };
    void setAge();
    int getWeight() const {
        return itsWeight;
    };
    void setWeight();
    //其它方法;
    void speak() const {
        cout<<"Mammal sound\n";
    };
    void sleep() const {
        cout<<"Mammal.zZzZ..";
    };
protected:
    int itsAge;
    int itsWeight;
};
//
class Dog : public Mammal{
public:
    //初始化狗狗类型
    Dog():itsBreed(GOLDEN){
    };
    ~Dog(){};

    BREED getBreed() const {
        return itsBreed;
    }
    void setBreed(BREED breed) {
        itsBreed = breed;
    }
    //其它方法
    void wagTail() const {
        cout<<"wag tail \n";
    }
    void begForFood() const{
        cout<<"begging for food \n";
    }
private:
    BREED itsBreed;
};
int main() {
    Dog d;
    d.wagTail();
    d.begForFood();
    cout << " the breed of dog is ";
    cout << d.getBreed();
    cout << endl;
    return 0;
}
复制代码

  通过继承实现一只小狗🐶  :

运行下面代码

复制代码
#include <iostream>
using namespace std;
enum BREED{GOLDEN, DANDIE, LAB};
class Mammal{
public:
    Mammal();
    Mammal(int age);
    ~Mammal(){};
    //访问器和设置器;
    int getAge() const {
        return itsAge;
    };
    void setAge();
    int getWeight() const {
        return itsWeight;
    };
    void setWeight();
    //其它方法;
    void speak() const {
        cout<<"Mammal sound\n";
    };
    void sleep() const {
        cout<<"Mammal.zZzZ..";
    };
protected:
    int itsAge;
    int itsWeight;
};
class Dog : public Mammal{
public:
    Dog();
    Dog(int age);
    Dog(int age , int weight);
    Dog(int age, int weight, BREED breed);
    BREED getBreed() const {
        return itsBreed;
    }
    void setBreed(BREED breed) {
        itsBreed = breed;
    }
    //其它方法
    void wagTail() const {
        cout << "wag tail \n";
    }
    void begForFood() const{
        cout << "begging for food \n";
    }
    void show() {
        cout << itsAge << "\n";
        cout << itsWeight << "\n";
        cout << itsBreed << "\n";
    }
private:
    BREED itsBreed;
    int itsAge;
    int itsWeight;
};
Mammal::Mammal():itsAge(1),itsWeight(1) {
    cout << "MaMMal constructor" << endl;
}
Mammal::Mammal(int age): itsAge(age), itsWeight(5) {
    cout << "MaMMal constructor " << endl;
}
Dog::Dog(){}
Dog::Dog(int age):itsAge(age){}
Dog::Dog(int age, int weight):itsAge(age),itsWeight(weight){}
Dog::Dog(int age, int weight, BREED breed):itsAge(age),itsWeight(weight),itsBreed(breed){}
int main() {
    Dog d(2,2,GOLDEN);
    d.show();
    return 0;
}
复制代码

   使用继承的时候要注意,如果子类使用继承覆盖了父类的一个方法, 父类的其它同名的方法也要覆盖, 如果不希望它们被隐藏, 必须对其进行覆盖:

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Mammal{
public:
    Mammal();
    ~Mammal(){};
    //其它方法;
    void speak() const {
        cout << "Mammal sound\n";
    };
    void sleep() const {
        cout << "Mammal.zZzZ..";
    };
    void move() const {
        cout << "mammal move one step\n"; 
    }
    void move(int st) const {
        cout << "mammal move "<< st <<" step\n"; 
    }
};
class Dog : public Mammal{
public:
    Dog();
    ~Dog(){};
    //其它方法
    void wagTail() const {
        cout << "wag tail \n";
    }
    void begForFood() const{
        cout << "begging for food \n";
    }
    void move() const {
        cout << "dog move two step\n"; 
    }
};
Mammal::Mammal(){}
Dog::Dog(){}
int main() {
    Mammal m;
    Dog d;
    m.move();
    d.move();
    m.move(2);
    //这一句报错了, 因为Dog没有重载Mammal的move( int step)方法 
    //d.move(2);
    return 0;
}    
复制代码

   子类要调用父类的相关方法,有两种调用方式,

  第一种是:子类.父类方法();

  第二种是:子类.父级构造函数::父级方法()

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Mammal{
public:
    Mammal();
    ~Mammal(){};
    //其它方法;
    void speak() const {
        cout << "Mammal sound\n";
    };
    void sleep() const {
        cout << "Mammal.zZzZ..\n";
    };
};
class Dog : public Mammal{
public:
    Dog();
    ~Dog(){};
    //其它方法
    void wagTail() const {
        cout << "wag tail \n";
    }
    void begForFood() const{
        cout << "begging for food \n";
    }
};
Mammal::Mammal(){}
Dog::Dog(){}
int main() {
    Dog d;
    d.sleep(); //第一种调用方式
    d.Mammal::sleep(); //第二种调用方式
    return 0;
}
复制代码

  虚拟函数:

  如果我创建了一个子类对象, 对象的指针却指向了父类, 问题来了, 我要调用这个实例的方法, 会执行父类的方法,还说子类的方法呢:

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Mammal{
public:
    Mammal();
    ~Mammal(){};
    //其它方法;
    void speak() const {
        cout << "Mammal sound\n";
    };
    void sleep() const {
        cout << "Mammal.zZzZ..\n";
    };
};
class Dog : public Mammal{
public:
    Dog();
    ~Dog(){};
    //其它方法
    void speak() const {
        cout << "Dog sound\n";
    };
    void sleep() const {
        cout << "Dog.zZzZ..\n";
    };
};
Mammal::Mammal(){}
Dog::Dog(){}
int main() {;
    Dog d;
    d.speak();
    d.sleep();
    Mammal * m = new Dog();
    m->speak();
    m->sleep();
    return 0;
}
复制代码

  实际上指针是啥类型的, 那么就会调用对应构造函数下的方法;

  虚方法的作用就会体现出来,无论指针是指向父类还是子类, 只要确定创建实例的构造函数是哪一个,那么就会调用对应构造函数下的方法,

  在父类的构造方法上添加virtual关键字, virtual是可以继承的, 只要父类写了一个virtual, 会自动继承到子类去:

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Mammal{
public:
    Mammal();
    ~Mammal(){};
    //其它方法;
    virtual void speak() const {
        cout << "Mammal sound\n";
    };
    virtual void sleep() const {
        cout << "Mammal.zZzZ..\n";
    };
};
class Dog : public Mammal{
public:
    Dog();
    ~Dog(){};
    //其它方法
    void speak() const {
        cout << "Dog sound\n";
    };
    void sleep() const {
        cout << "Dog.zZzZ..\n";
    };
};
Mammal::Mammal(){}
Dog::Dog(){}
int main() {;
    Dog d;
    d.speak();
    d.sleep();
    Mammal * m = new Dog();
    m->speak();
    m->sleep();
    return 0;
}
复制代码

  虚函数有啥用呢

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Mammal{
public:
    Mammal(){};
    ~Mammal(){};
    virtual void sleep() const {
        cout << "Mammal.zZzZ..\n";
    };
};
class Dog : public Mammal{
public:
    Dog(){};
    ~Dog(){};
    void sleep() const {
        cout << "Dog.zZzZ..\n";
    };
};
class Bird : public Mammal{
public:
    Bird(){};
    ~Bird(){};
    void sleep() const {
        cout << "Bird.zZzZ..\n";
    };
};
int main() {
    Mammal* arr[3];
    int i;
    for(i=0; i<3; i++) {
        Mammal* m;
        switch(i) {
            case 0:
                m = new Mammal();
            break;
            case 1:
                m = new Dog();
            break;
            case 2:
                m = new Bird();
            break;
        }
        arr[i] = m;
    }
    for(i=0; i<3; i++) {
        arr[i]->sleep();
    }
    return 0;
}
复制代码

  只要定义一种数据类型的数组, 数组中的元素全部为子类;

  虚函数耶可以作为纯接口函数使用, 子类负责实现:

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Animal{
public:
    virtual void eat() = 0;
};
class Cat:public Animal{
public:
    void eat() {
        cout << "eat it ....ing" << endl;
    }
};
int main() {
    Cat c;
    c.eat();//eat it ....ing
    return 0;
}
复制代码

 

  以下一个案例要了解一下, 当使用虚函数的时候, 如果把子类强转为父类型, 那么就会损失子类定义的方法和属性:

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Mammal{
public:
    Mammal(){};
    ~Mammal(){};
    virtual void sleep() const {
        cout << "Mammal.zZzZ..\n";
    };
};
class Dog : public Mammal{
public:
    Dog(){};
    ~Dog(){};
    void sleep() const {
        cout << "Dog.zZzZ..\n";
    };
};
class Bird : public Mammal{
public:
    Bird(){};
    ~Bird(){};
    void sleep() const {
        cout << "Bird.zZzZ..\n";
    };
};
void refFn(Mammal& m) {
    m.sleep();
}
void ptrFn(Mammal* m) {
    m->sleep();
}
void slice(Mammal m) {
    m.sleep();
}
int main() {
    Mammal* arr[3];
    int i;
    for(i=0; i<3; i++) {
        Mammal* m;
        switch(i) {
            case 0:
                m = new Mammal();
            break;
            case 1:
                m = new Dog();
            break;
            case 2:
                m = new Bird();
            break;
        }
        arr[i] = m;
    }
    for(i=0; i<3; i++) {
        //refFn(*arr[i]);
        //ptrFn(arr[i]);
        slice(*arr[i]);
    }
    return 0;
}
复制代码

  所以要加油啊

  私有继承的方法和属性无法直接访问,只能通过子类的方法访问, 注意下面的private关键字:

运行下面代码

复制代码
#include <iostream>
using namespace std;
//私有继承
class Elec{
public:
    Elec() {};
    void start() {
        cout << "start ....ing" << endl;
    }
    void stop() {
        cout << "stop ....ing" << endl;
    }
};
class Fan : private Elec{
public:
    void run() {
        start();
    }
    void unRun() {
        stop();
    }
};
int main() {
    Fan f;
    f.run();
    f.unRun();
    //因为使用的是私有继承, 所以无法调用f的start和stop方法;
    //f.start();
    //f.stop();
    return 0;
}
复制代码

  如果不使用继承,通过组合也可以实现效果:

运行下面代码

复制代码
#include <iostream>
using namespace std;
//私有继承
class Elec{
public:
    Elec() {};
    void start() {
        cout << "start ....ing" << endl;
    }
    void stop() {
        cout << "stop ....ing" << endl;
    }
};
class Fan{
private:
    Elec elec;
public:
    void run() {
        elec.start();
    }
    void unRun() {
        elec.stop();
    }
};
int main() {
    //组合的方式实现继承;
    Fan f;
    f.run();
    f.unRun();
    return 0;
}
复制代码

  算术运算符的重载, 重载+号:

运行下面代码

复制代码
#include <iostream>
using namespace std;
//重载算术运算符
class Date{
public:
    Date();
    ~Date(){};
    Date operator+ (int i) {
        cout << "nice gay" << endl;
        cout << i << endl;
        return *this;
    }
};
Date::Date(){};
int main() {
    Date date;
    date+10;
    return 0;
}
复制代码

 

  重载++运算符:

运行下面代码

复制代码
#include <iostream>
using namespace std;
//重载算术运算符
class Date{
private:
    int day;
public:
    Date();
    ~Date(){};
    Date operator++ () {
        day++;
        return *this;
    }
    int getDay() {
        return day;
    }
};
Date::Date():day(0){};
int main() {
    Date date;
    ++date;
    ++date;
    cout << "now is " << date.getDay() << endl;
    return 0;
}
复制代码

   通过使用智能指针, 可以实现自动释放申请到的内存:

运行下面代码

复制代码
#include <iostream>
using namespace std;
class Dog{
public:
    Dog() {
    }
    ~Dog() {
        cout << "destructor Dog"  << endl;
    }
    void bark() {
        cout << "bark.wa.wa.wa" << endl;
    }
};
int main() {
    auto_ptr <int> p (new int);
    *p = 21;
    cout << *p <<endl;
    auto_ptr <Dog> pd (new Dog);
    pd->bark();
    return 0;
}
复制代码

  可以通过一些重载方法,让实例对象转换为数字, 或者让对象转换为字符串:

运行下面代码

复制代码
#include <iostream>
class Dog{
public:
    operator int() {
        return 100;
    }
    operator std::string() {
        return "abcd";
    }
};
int main() {
    Dog dg;
    int index = dg;
    std::cout << "index is " << dg << std::endl;
    std::string str(dg);
    std::cout << "string is " << str << std::endl;
    return 0;
}
复制代码

   在说智能指针之前,有必要复习一下,模版(泛型)的创建, 泛型的实例化:

运行下面代码

复制代码
#include <iostream>
using namespace std;
template<typename T>
class Dog{
private:
    T i;
public:
    Dog(T _i) {
        i = _i;
    }
    ~Dog() {
        cout << "destructor Dog"  << endl;
    }
    void bark() {
        cout << "my xx is " << i << endl;
    }
};
int main() {
    Dog<int> d(1);
    d.bark();
    Dog<char> dd('a');
    dd.bark();
    return 0;
}
复制代码

  如何去实现一个智能指针, 有了智能指针,就可以防止申请了内存, 又忘记清空:

运行下面代码

复制代码
#include <iostream>
template <typename T>
class smart_pointer{
private:
    T* ptr;
public:
    smart_pointer(T* p):ptr(p){};
    ~smart_pointer() {
        delete ptr;
    }
    //smart_pointer& operator=(const smart_pointer& anotherPtr);
    T& operator*() {
        return *ptr;
    }
    T* operator->() {
        return ptr;
    }
};
using namespace std;
class Dog{
public:
    Dog() {
    }
    ~Dog() {
        cout << "destructor Dog"  << endl;
    }
    void bark() {
        cout << "bark.wa.wa.wa" << endl;
    }
};
int main() {
    //这两种写法都可以
    // smart_pointer<Dog> p = new Dog();
    smart_pointer<Dog> p(new Dog);
    p->bark();
    // Dog* d = new Dog();
    // d->bark();
    return 0;
}
复制代码

   模版关键字:

运行下面代码

复制代码
#include <stdio.h>
template<typename T>
void swap(T & t, T & t1) {
    T tmp = t;
    t = t1;
    t1 = tmp;
    return ;
}
int main() {
    int i = 1;
    int j = 2;
    swap<int>(i, j);
    printf("%d, %d",i, j);
    // cout << i << endl;
    // cout << j << endl;
    return 0;
}
复制代码

   模版关键字实现一个固定长度的数组:

运行下面代码

复制代码
#include <stdio.h>
#include <iostream>
template<class T>
class Array {
public:
    Array();
    ~Array();
    void push(const T& t);
    T pop();
private:
    int maxSize;
    int nowIndex;
    T* newData;
};

template<class T>Array<T>::Array():maxSize(100), nowIndex(0) {    
    newData = new T[maxSize];
    std::cout << "new T" << std::endl;
}
template<class T>Array<T>::~Array() {
    delete newData;
    std::cout << "destructing" << std::endl;
}
template<class T>void Array<T>::push(const T& t) {
    newData[nowIndex] = t;
    nowIndex = ++nowIndex>=maxSize ? maxSize : nowIndex;
}
template<class T>T Array<T>::pop() {
    nowIndex = nowIndex-- >=0 ? nowIndex : 0;
    return newData[nowIndex];
}
int main() {
    Array<int> array;
    array.push(100);
    array.push(2);
    std::cout << array.pop()+array.pop() << std::endl;
    return 0;
}
复制代码

  以上代码的简化版:

运行下面代码

复制代码
#include <stdio.h>
#include <iostream>
template<class T>
class Array {
public:
    Array():maxSize(100), nowIndex(0) {    
        newData = new T[maxSize];
        std::cout << "new T" << std::endl;
    }
    ~Array() {
        delete newData;
        std::cout << "destructing" << std::endl;
    }
    void push(const T& t) {
        newData[nowIndex] = t;
        nowIndex = ++nowIndex>=maxSize ? maxSize : nowIndex;
    }
    T pop() {
        nowIndex = nowIndex-- >=0 ? nowIndex : 0;
        return newData[nowIndex];
    }
private:
    int maxSize;
    int nowIndex;
    T* newData;
};
int main() {
    Array<int> array;
    array.push(100);
    array.push(2);
    std::cout << array.pop()+array.pop() << std::endl;
    return 0;
}
复制代码

 

 

 

 

eof

 

 

eof

本文作者:方方和圆圆

本文链接:https://www.cnblogs.com/diligenceday/p/6046605.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   方方和圆圆  阅读(1071)  评论(0编辑  收藏  举报

再过一百年, 我会在哪里?

💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
点击右上角即可分享
微信分享提示