zoukankan      html  css  js  c++  java
  • 虚继承

    ------------------siwuxie095

       

       

       

       

       

       

       

       

       

       

       

       

    看如下实例:

       

    4 个类,其中:类 A 是父类,类 B 和 类 C 都继承 类 A,

    D 继承了 类 B 和 类 C,称这种继承关系为 菱形继承

       

       

       

       

    在菱形继承中,既有多继承,又有多重继承:

       

       

       

       

       

       

    那么问题来了:

       

    当实例化 D 的对象时,发现:D 是从 B 继承来的,B 是从 A 继承来的,

    D 也是从 C 继承来的,C 是从 A 继承来的

       

    这样,D 中将含有两个完全一样的 A 的数据,这种情况是不能容忍的,

    因为在一个对象中有两份完全相同的数据,无法承担这种冗余数据带来

    的系统开销,所以必须要解决

       

       

       

       

    也许,你会说在实际的工作中会遇到这么复杂的情况吗?

    看如下实例:人、工人、农民、农民工间的菱形继承关系

       

       

       

       

    那么,可以使用 虚继承 来解决这种典型的菱形继承关系带来的数据冗余问题

       

       

       

       

    虚继承

       

       

    虚继承 是继承的一种方式,关键字:virtual

       

       

    看如下实例:virtual 可以写在 public 的前面 或 后面,推荐前面

       

    其中:Worker 和 Farmer 都 虚继承 自 Person

       

       

       

       

    在使用时:

       

    MigrantWorker 可以继承自 Worker 和 Farmer 这两个类,并称 Worker

    Farmer 为 虚基类,当使用 MigrantWorker 实例化一个对象时,它当

    中只含有一份 Person 的数据

       

       

       

       

       

       

       

       

    程序 1:不使用虚继承

       

    Person.h:

       

    #ifndef PERSON_H

    #define PERSON_H

       

    //重定义,即在当前的工程中,Person被定义了两遍,因为在子类包含了两个 Person.h

    //

    //在菱形继承中重定义必然会出现

    //用宏定义来解决重定义,避免了重复包含

    //具体用法:在公共被继承的类中写上宏定义

    //

    //推荐不是公共被继承的类也写上,将来这个类被其他类继承时就不会出现重定义

       

    #include <string>

    using namespace std;

       

       

    class Person

    {

    public:

    Person(string color = "yellow");

    virtual ~Person();//虚析构函数

    void printColor();

    protected:

    string m_strColor;//肤色

    };

       

       

    #endif

       

       

       

    Person.cpp:

       

    #include "Person.h"

    #include <iostream>

    using namespace std;

       

       

    Person::Person(string color)

    {

    m_strColor = color;

    cout << "Person()" << endl;

    }

       

    Person::~Person()

    {

    cout << "~Person()" << endl;

    }

       

    void Person::printColor()

    {

    cout << "Person--printColor()" << endl;

    cout << m_strColor << endl;

    }

       

       

       

    Farmer.h:

       

    #include "Person.h"

    #include <string>

    using namespace std;

       

       

    class Farmer :public Person

    {

    public:

    Farmer(string name = "Jack", string color = "yellow");

    virtual ~Farmer();//虚析构函数

    void sow();

    protected:

    string m_strName;

    };

       

       

       

    Farmer.cpp:

       

    #include "Farmer.h"

    #include <iostream>

    using namespace std;

       

       

    //colorstring型数据所以可以用 + 的形式来将 "Farmer " 同时传进去作为标记

    Farmer::Farmer(string name, string color) :Person("Farmer "+color)

    {

    m_strName = name;

    cout << "Farmer()" << endl;

    }

       

    Farmer::~Farmer()

    {

    cout << "~Farmer()" << endl;

    }

       

    void Farmer::sow()

    {

    cout << "Farmer--sow()" << endl;

    cout << m_strName << "," << m_strColor << endl;

    }

       

       

       

    Worker.h:

       

    #include "Person.h"

    #include <string>

    using namespace std;

       

       

    class Worker:public Person

    {

    public:

    //希望Worker可以传入肤色给Person

    //使得Person能从Worker的参数列表中拿到肤色的这个参数

    Worker(string code = "001", string color = "yellow");

    virtual ~Worker();//虚析构函数

    void carry();

    protected:

    string m_strCode;

    };

       

       

       

    Worker.cpp:

       

    #include "Worker.h"

    #include <iostream>

    using namespace std;

       

       

    //colorstring型数据所以可以用 + 的形式来将 "Worker " 同时传进去作为标记

    Worker::Worker(string code, string color) :Person("Worker "+color)

    {

    m_strCode = code;

    cout << "Worker()" << endl;

    }

       

    Worker::~Worker()

    {

    cout << "~Worker()" << endl;

    }

       

    void Worker::carry()

    {

    cout << "Worker--worker()" << endl;

    cout << m_strCode << "," << m_strColor << endl;

    }

       

       

       

    MigrantWorker.h:

       

    #include "Farmer.h"

    #include "Worker.h"

       

    class MigrantWorker:public Farmer,public Worker

    {

    public:

    MigrantWorker(string name, string code, string color);

    virtual ~MigrantWorker();//虚析构函数

    };

       

       

       

    MigrantWorker.cpp:

       

    #include "MigrantWorker.h"

    #include <iostream>

    using namespace std;

       

       

    MigrantWorker::MigrantWorker(string name, string code, string color) :Farmer(name, color),

    Worker(code, color)

    {

    cout << "MigrantWorker()" << endl;

    }

       

    MigrantWorker::~MigrantWorker()

    {

    cout << "~MigrantWorker()" << endl;

    }

       

       

       

    main.cpp:

       

    #include <stdlib.h>

    #include "MigrantWorker.h"

    #include <iostream>

    using namespace std;

       

       

    int main(void)

    {

    //从堆中实例化,用指针指向堆中的这块内存

    MigrantWorker *p = new MigrantWorker("Merry", "200", "white");

    cout << endl;

       

    //这两行代码说明了Person类在MigrantWorker类中有两份数据

    //MigrantWorker类中有两份继承自Person类的数据数据冗余系统开销太大

    p->Farmer::printColor();

    p->Worker::printColor();

    cout << endl;

       

    delete p;

    p = NULL;

    system("pause");

    return 0;

    }

       

       

    运行一览:

       

       

       

       

       

       

    程序 2:使用虚继承

       

    Person.h:

       

    #ifndef PERSON_H

    #define PERSON_H

    #include <string>

    using namespace std;

       

       

    class Person

    {

    public:

    Person(string color = "yellow");

    virtual ~Person();

    void printColor();

    protected:

    string m_strColor;

    };

       

    #endif

       

       

       

    Person.cpp:

       

    #include "Person.h"

    #include <iostream>

    using namespace std;

       

       

    Person::Person(string color)

    {

    m_strColor = color;

    cout << "Person()" << endl;

    }

       

    Person::~Person()

    {

    cout << "~Person()" << endl;

    }

       

    void Person::printColor()

    {

    cout << "Person--printColor()" << endl;

    cout << m_strColor << endl;

    }

       

       

       

    Farmer.h:

       

    #include "Person.h"

    #include <string>

    using namespace std;

       

       

    class Farmer :virtual public Person //Farmer变成了虚基类

    {

    public:

    Farmer(string name = "Jack", string color = "yellow");

    virtual ~Farmer();

    void sow();

    protected:

    string m_strName;

    };

       

       

       

    Farmer.cpp:

       

    #include "Farmer.h"

    #include <iostream>

    using namespace std;

       

       

    Farmer::Farmer(string name, string color) :Person("Farmer "+color)

    {

    m_strName = name;

    cout << "Farmer()" << endl;

    }

       

    Farmer::~Farmer()

    {

    cout << "~Farmer()" << endl;

    }

       

    void Farmer::sow()

    {

    cout << "Farmer--sow()" << endl;

    cout << m_strName << "," << m_strColor << endl;

    }

       

       

       

    Worker.h:

       

    #include "Person.h"

    #include <string>

    using namespace std;

       

       

    class Worker :virtual public Person //Worker变成了虚基类

    {

    public:

    Worker(string code = "001", string color = "yellow");

    virtual ~Worker();

    void carry();

    protected:

    string m_strCode;

    };

       

       

       

    Worker.cpp:

       

    #include "Worker.h"

    #include <iostream>

    using namespace std;

       

       

    Worker::Worker(string code, string color) :Person("Worker "+color)

    {

    m_strCode = code;

    cout << "Worker()" << endl;

    }

       

    Worker::~Worker()

    {

    cout << "~Worker()" << endl;

    }

       

    void Worker::carry()

    {

    cout << "Worker()" << endl;

    cout << m_strCode << "," << m_strColor << endl;

    }

       

       

       

    MigrantWorker.h:

       

    #include "Farmer.h"

    #include "Worker.h"

       

    class MigrantWorker :public Farmer, public Worker

    {

    public:

    MigrantWorker(string name, string code, string color);

    ~MigrantWorker();

    };

       

       

       

    MigrantWorker.cpp:

       

    #include "MigrantWorker.h"

    #include <iostream>

    using namespace std;

       

       

    MigrantWorker::MigrantWorker(string name, string code, string color) :Farmer(name, color),

    Worker(code, color)

    {

    cout << "MigrantWorker()" << endl;

    }

       

    MigrantWorker::~MigrantWorker()

    {

    cout << "~MigrantWorker()" << endl;

    }

       

       

       

    main.cpp:

       

    #include <stdlib.h>

    #include "MigrantWorker.h"

    #include <iostream>

    using namespace std;

       

    int main(void)

    {

    MigrantWorker *p = new MigrantWorker("Merry", "200", "white");

    cout << endl;

       

    //此时只会打印出yellow 说明在虚继承的情况下作为菱形继承最顶层的父类,

    //并没有进行参数的传递

    //

    //参数只使用了顶层父类的默认参数而无法从子类中获得传入的参数

    p->Farmer::printColor();

    p->Worker::printColor();

    cout << endl;

       

    /*p->carry();

    p->sow();*/

    delete p;

    p = NULL;

    system("pause");

    return 0;

    }

       

       

    运行一览:

       

       

       

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    php投票系统
    php登陆和注册
    php常见报错
    session和cookie的区别
    php加密方法有哪些
    链接数据库封装类
    php数据库批量删除
    三傻大闹宝莱坞
    巴霍巴利王
    布拉德的中年危机
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6804282.html
Copyright © 2011-2022 走看看