C++学习之路 day8

来源:互联网 发布:数据库集群 编辑:程序博客网 时间:2024/05/16 08:15

Day8 知识点:

1.赋值兼容

赋值兼容只能发生在公有派生继承的父子关系中。

a) 子类对象(派生类)赋给父类(基类)的对象

b) 子类对象赋给父类的引用

c) 子类对象的地址赋给父类的指针


实验代码:

#include <iostream>using namespace std;class shape{public:    shape(int x = 0, int y = 0)        :_x(x),_y(y){}    void draw()    {        cout<<"drawfrom"<<"("<<_x<<","<<_y<<")"<<endl;    }protected:    int _x;    int _y;};class circle:public shape{public:    circle(int x = 0, int y = 0, int r = 0)        :shape(x,y),_radius(r){}    void draw()    {        cout<<"drawfrom"<<"("<<_x<<","<<_y<<")";        cout<<" radius = "<<_radius<<endl;    }    void func()    {        cout<<"------------------"<<endl;    }private:    int _radius;};int main(){    shape s(1,2);    s.draw();    circle c(1,2,3);    c.draw();    c.func();    shape s1 = c;       //派生类对象赋给基类对象    s1.draw();    shape &rc = c;      //派生类对象赋给基类的引用    rc.draw();    shape *pc = &c;     //派生类对象的地址赋给指向基类的指针    pc->draw();    return 0;}




2.多态:由继承产生的相关的不同的类,对同一消息做出的不同响应。

静多态,编译阶段决定的

#include <iostream>using namespace std;void func(int a, float b){    cout<<"void func(int a, float b)"<<endl;}void func(float a, int b){    cout<<"void func(float a, int b)"<<endl;}int main(){    func(1,3.0);        //在编译阶段就完成函数的倾轧    func(3.0,1);    return 0;}


动多态,运行阶段决定的

实现条件:

1)父类中有虚函数(在函数声明前virtual定义时不需要)

2)子类中覆写(override)了父的虚函数,根据需要重新定义函数体

{

a)overload重载 同一作用域中,函数名相同,参数列表不同;

b)shadow 发生在父子类中的同名成员(函数或数据,如果是函数只要同名就会构成shadow);

c)override  发生在父子类中,父类中函数有virtual声明的函数,子类中同参同名同返回

   }

3)成员函数被声明为虚函数后,其子类中的完全相同的函数也是虚函数。可以加virtual以示清晰(也可不加)

4)定义一个父类的指针,将子类对象地址赋给父类的指针,通过该指针调用虚函数,调用的就是所指向子类中的虚函数

5)子类中覆写的函数可以是任意访问类型,依需求而定。

实验代码:

#include <iostream>using namespace std;class shape{public:    shape(int x = 0, int y = 0)        :_x(x),_y(y){}    virtual void draw()    {        cout<<"drawfrom"<<"("<<_x<<","<<_y<<")"<<endl;    }protected:    int _x;    int _y;};class Circle:public shape{public:    Circle(int x = 0, int y= 0, int r = 0)        :shape(x,y),_radius(r){}    virtual void draw()    {        cout<<"drawfrom"<<"("<<_x<<","<<_y<<")";        cout<<" _radius ="<<_radius<<endl;    }private:    int _radius;};class Rec:public shape{public:    Rec(int x = 0, int y = 0,int len = 0, int wid = 0 )        :shape(x,y),_len(len),_wid(wid){}    virtual void draw()    {        cout<<"drawfrom"<<"("<<_x<<","<<_y<<")";        cout<<" _len ="<<_len<<" _wid= "<<_wid<<endl;    }private:    int _len;    int _wid;};int main(){    Circle c(1,2,3);    c.draw();    Rec r(1,2,3,4);    r.draw();    shape *ps = NULL;    int choice;    while(1)    {        scanf("%d",&choice);        switch(choice)        {            case 1:                ps = &c;                ps->draw();            break;            case 2:                ps = &r;                ps->draw();            break;        }    }    return 0;}


3.

virtual void draw() = 0;纯虚函数格式1.含有纯虚函数的类,称为抽象基类,不可实列化。即不能创建对象,存在的意义就是被继承,提供族类的公共接口,java 中称为 interface;2. 纯虚函数只有声明,没有实现,被“初始化”为 0;3. 如果一个类中声明了纯虚函数,而在派生类中没有对该函数定义,则该虚函数在派生类中仍然为纯虚函数,派生类仍然为纯虚基类。


实例代码:

#include <iostream>using namespace std;class shape{public:    shape(int x = 0, int y = 0)        :_x(x),_y(y){}    virtual void draw() = 0;protected:    int _x;    int _y;};class Circle:public shape{public:    Circle(int x = 0, int y= 0, int r = 0)        :shape(x,y),_radius(r){}    virtual void draw()    {        cout<<"drawfrom"<<"("<<_x<<","<<_y<<")";        cout<<" _radius ="<<_radius<<endl;    }private:    int _radius;};class Rec:public shape{public:    Rec(int x = 0, int y = 0,int len = 0, int wid = 0 )        :shape(x,y),_len(len),_wid(wid){}    virtual void draw()    {        cout<<"drawfrom"<<"("<<_x<<","<<_y<<")";        cout<<" _len ="<<_len<<" _wid= "<<_wid<<endl;    }private:    int _len;    int _wid;};int main(){    Circle c(1,2,3);    Rec r(3,4,5,6);    shape *ps = &c;    ps->draw();    ps = &r;    ps->draw();    return 0;}



4.虚析构(在析构器前加virtual)

目的:为了析构完全,在delete父类指针的时候,会调用子类的析构函数,实现完整析构。

 使用方法:当一个类中有虚函数的时候,将其析构函数一并加上virtual

实验代码:

//animal.h#ifndef ANIMAL_H#define ANIMAL_Hclass Animal{public:    Animal();    virtual ~Animal();          //如果不加virtual,在释放堆内存的时候只会对Animai进行析构,    virtual void voice() = 0;   //Animal指针指向的内存不会自动完成析构};#endif // ANIMAL_H
//cat.h#ifndef CAT_H#define CAT_H#include "animal.h"class Cat:public Animal{public:    Cat();    ~Cat();    virtual void voice();};#endif // CAT_H
//dog.h#ifndef DOG_H#define DOG_H#include "animal.h"class Dog:public Animal{public:    Dog();    ~Dog();    void voice();};#endif // DOG_H
//animal.cpp#include "animal.h"#include <iostream>using namespace std;Animal::Animal(){    cout<<"Animal()"<<endl;}Animal::~Animal(){    cout<<"~Animal()"<<endl;}
//cat.cpp#include "cat.h"#include <iostream>using namespace std;Cat::Cat(){    cout<<"Cat()"<<endl;}Cat::~Cat(){    cout<<"~Cat()"<<endl;}void Cat::voice(){    cout<<"I am a cat,miao miao miao"<<endl;}
//dog.cpp#include "dog.h"#include <iostream>using namespace std;Dog::Dog(){    cout<<"Dog()"<<endl;}Dog::~Dog(){    cout<<"~Dog()"<<endl;}void Dog::voice(){    cout<<"I am a dog,wang wang wang"<<endl;}
//main.cpp#include <iostream>#include "animal.h"#include "cat.h"#include "dog.h"using namespace std;int main(){    Dog d;    Cat c;    Animal *a1 = &d;    Animal *a2 = &c;    a1->voice();    a2->voice();            Animal *a = new Dog;    delete a;    return 0;}


5.基于多态的依赖倒置设计原则


依赖倒置定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象

下面以两种不同的程序设计方法来表达设计思想


场景是这样的,母亲给孩子讲故事,只要给她一本书,她就可以照着书给孩子讲故事了。


传统过程设计:

实验代码:

#include <iostream>using namespace std;class Book{public:    string getContents()    {        return "A little bear are crying";    }};class News{public:    string getContents()    {        return "Mr.Zhou were awarded with the Noble Prize";    }};class Mother{public:    void tellContents(Book *b)    {        cout<<b->getContents()<<endl;    }    void tellContents(News *n)    {        cout<<n->getContents()<<endl;    }};int main(){    Mother m;    Book b;    News n;    m.tellContents(&b);    m.tellContents(&n);    return 0;}





依赖倒置设计原则:


#include <iostream>using namespace std;class Ireader{public:    virtual string getContents() = 0;};class Book:public Ireader{public:    virtual string getContents()    {        return "A little bear are crying";    }};class News:public Ireader{public:    virtual string getContents()    {        return "Mr.Zhou were awarded with the Noble Prize";    }};class Mother{public:    void tellContents(Ireader *i)    {        cout<<i->getContents()<<endl;    }};int main(){    Mother m;    Book b;    News n;    m.tellContents(&b);    m.tellContents(&n);    return 0;}

电脑组装实验代码:

#include <iostream>using namespace std;class CPU{public:    virtual void run() = 0;};class Mem{public:    virtual void run() = 0;};class Disk{public:    virtual void run() = 0;};class Intel:public CPU{public:    virtual void run()    {        cout<<"Intel CPU"<<endl;    }};class Kingston:public Mem{public:    virtual void run()    {        cout<<"Kingston Mem"<<endl;    }};class Wddisk:public Disk{public:    virtual void run()    {        cout<<"Wddisk"<<endl;    }};class Computer{public:    Computer(CPU *pc,Mem *pm,Disk *pd)        :_pc(pc),_pm(pm),_pd(pd){}    void work()    {        _pc->run();        _pm->run();        _pd->run();    }    ~Computer()    {        delete _pc;        delete _pm;        delete _pd;    }private:    CPU *_pc;    Mem *_pm;    Disk *_pd;};int main(){    Computer c(new Intel,new Kingston,new Wddisk);    c.work();    return 0;}












原创粉丝点击