日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多重继承之虚继承(主要是为了解决产生的数据冗余问题)

發布時間:2023/11/30 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多重继承之虚继承(主要是为了解决产生的数据冗余问题) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
虛繼承?是面向對象編程中的一種技術,是指一個指定的基類,在繼承體系結構中,將其成員數據實例共享給也從這個基類型直接或間接派生的其它類。形式:在繼承定義中包含了virtual關鍵字的繼承關系,如下圖中,類A就叫做虛基類。 虛擬繼承是多重繼承中的菱形繼承所特有的概念。虛擬基類是為解決多重繼承而出現的。
菱形繼承中既有多繼承,如下圖所示:
菱形繼承中也有多重繼承:
?現實中的例子:



問題來了:在類D的實例中將有兩份類A的變量,這種數據冗余的現象我們不能容忍其存在?這就會需要用到虛繼承!!!廢話不多說直接上代碼,直接粘貼可用。

#include <iostream>

#include <stdlib.h>
#include <string>
using namespace std;


/**
?* 定義人類: Person
?*/
class Person
{
public:
? ? Person(string color = "blue"):m_strColor(color)
{
cout << "Person" << endl;
}
~Person()
{
cout << "~Person" << endl;
}
void eat()
{
? ? ? ? cout << m_strColor << endl;
? ? ? ? // cout << m_iAge << endl;
cout << "Person -- eat" << endl;
}
protected:
? ? string m_strColor;
};


/**
?* 定義工人類: Worker
?* 虛繼承人類
?*/
class Worker : ?virtual?public Person
{
public:
Worker(string name,string color):Person("Worker"+color)
{
m_strName = name;
cout << "Worker" << endl;
}
~Worker()
{
cout << "~Worker" << endl;
}
void work()
{
cout << m_strName << endl;
cout << "work" << endl;
}
protected:
string m_strName;
};


/**
?* 定義兒童類:Children
?* 虛繼承人類
?*/
class Children :?virtual?public Person
{
public:
Children(int age,string color):Person("Children"+ color)
{
m_iAge = age;
cout << "Children" << endl;
}
~Children()
{
cout << "~Children" << endl;
}
void play()
{
? ? ? ? cout<<
cout << m_iAge << endl;
cout << "play" << endl;
}
protected:
int m_iAge;
};


/**
?* 定義童工類:ChildLabourer
?* 公有繼承工人類和兒童類
?*/
class ChildLabourer:public Children,public Worker
{
public:
ChildLabourer(string name, int age,string color):Worker(name,color),Children(age,color)
{
cout << "ChildLabourer" << endl;
}


~ChildLabourer()
{
cout << "~ChildLabourer" << endl;
}
};


int main(void)
{
? ? // 用new關鍵字實例化童工類對象
ChildLabourer * p = new ChildLabourer("qq",14,"yellow");
? ? // 調用童工類對象各方法。
// ? p->eat();
? ? ? ? p->Worker::eat();
? ? ? ? p->Children::eat();
p->work();
p->play();
delete p;
p = NULL;


return 0;

}

輸出:

Person Children Worker ChildLabourer blue Person -- eat blue Person -- eat qq work 0x60314814 play ~ChildLabourer ~Worker ~Children ~Person 如果不加virtual關鍵字時候的輸出:

Person Children Person Worker ChildLabourer Workeryellow Person -- eat Childrenyellow Person -- eat qq work 0x60310814 play ~ChildLabourer ~Worker ~Person ~Children ~Person 分析:

(1)不加virtual情況:

不加virtual,也就是不是虛繼承的情況下,在實例化童工這個類的時候,會按繼承順序,先調用類Children的構造函數再調用類Worker的構造函數,最后調用自己的構造函數,而調用Children和Worker的構造函數的時候又會分別先調用它們的基類Person的構造函數,這樣就會生成兩個Person的對象,從而生成兩份Person所含有的數據成員,即童工類ChildLabourer在實例化的時會生成在內存中會生成兩份Person的數據成員,所以在調用Children和Worker的eat()函數的時候,會分別打印出Workeryellow和Childrenyellow,(這里注意Children和Worker里面的eat()都是從Person繼承來的,因此分別都會打印出Person --eat;還要注意調用方式:p->Worker::eat();p->Children::eat())

銷毀對象時,會先調用自己的析構函數,再調用兩個基類的析構函數,兩個基類的析構函數調用之前都會先調用Person的析構函數。調用析構函數的順序和調用構造函數相反。

(2)加virtual的情況:

加virtual以后,從輸出結果可以看出,在實例化童工類ChildrenLabourer時,構造函數的調用順序比較正常,只調用了一次Person,析構函數的調用也只會調用一次Person的析構函數,這說明實例化童工類時只會生成一份Person的對象,表明了在對象的內存空間中僅僅能夠包含一份虛基類的對象,而且打印的結果都是blue,即ChildrenLabourer的數據不會再傳入虛基類Person。這就講數據冗余的問題解決了。

總結

以上是生活随笔為你收集整理的多重继承之虚继承(主要是为了解决产生的数据冗余问题)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。