-
<table><tbody><tr class="firstRow"><td>123</td><td><code>Person *p=</code><code>new</code> <code>Soldier;</code><code>//用父類Person的指針指向堆中分配的子類Soldier的對象</code><code>delete</code> <code>p;</code><code>p=NULL;</code><code>//只執行父類的析構函數,而不執行子類的析構函數,可能導致內存泄露</code></td></tr></tbody></table><p>【如何在這種情況下防止內存泄露?】</p><p>虛析構函數:當存在繼承關系,且要用一個父類的指針指向堆中子類的對象,并希望用父類的指針釋放這塊內存時,可以使用。</p><table ><tbody><tr class="firstRow"><td>12345</td><td><code>class</code> <code>Person{</code><code> </code><code>Person();</code><code> </code><code>virtual</code><code>~Person(); </code><code>//前面加關鍵字virtual即可,這個關鍵字可以被繼承下去</code><code>}</code><code>//在Soldier.h中,即使在~Soldier前面不寫virtual,也相當于有了這個關鍵字(被繼承下來了)</code></td></tr></tbody></table><p>!</p><p><br/></p>查看全部
-
派生類的對象可以賦值的基類,而基類的對象不能賦值給派生類
123456 Soldier?s1;
Person?p1=s1;
Person?*p2=&s1;
//這三行是正確的
?s1=p1;
Soldier?*s2=&p1;
//這兩行是錯誤的
對于作為函數參數時:
1234567 void
?fun(Person?*p){...}
int
?main(){
????
Person?p1;
????
Soldier?s1;
????
fun(&p1);
????
fun(&s1);
//這兩種都是正確的
}
用子類對象初始化父類對象時,從父類中繼承下來的屬性會被初始化,而子類中特有的屬性則會被截斷(不會賦值給父類)。
查看全部 -
子類和父類中的同名函數不能進行重載,只能進行隱藏。
查看全部 -
私有繼承中,在子類中可以訪問父類的保護成員。B類由A類私有派生,那么在B類中可以訪問A類的public、protected,但是不能訪問A類的private。在B類外,B類對象不能訪問A類的成員,只能訪問B類的public。C類由B類私有派生,那么C類中不能訪問B類的private(其中包含了A類的public、protected),但是可以訪問B類的public、protected。在C類外,C類對象只能訪問C類的public。
查看全部 -
private繼承方式 ? 基類成員訪問屬性 ? 派生類成員訪問屬性
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? private成員 ? ? ? ? ? ?無法訪問
????????????????????????????????protected成員 ? ? ?private
????????????????????????????????public成員 ? ? ? ? ? ? private
查看全部 -
protected 繼承方式: 基類成員訪問屬性 ? ? 派生類成員訪問屬性
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? private成員 ? ? ? ? ? ? ? 無法訪問
? ?????????????????????????????????protected成員 ? ? ? ? ?protected
????????????????????????????????? ?public成員 ? ? ? ? ? ? ? ?protected
查看全部 -
public繼承方式:基類成員訪問屬性 ? ?派生類成員訪問屬性
? ? ? ? ? ? ? ? ? ? ? ? ? private成員 ? ? ? ? ? ? ? ?無法訪問
????????????????????????????protected成員 ? ? ? ? ?protected
????????????????????????????public成員 ? ? ? ? ? ? ? ?public
查看全部 -
公有繼承:class A : public B
保護繼承: class A : protected B
私有繼承; class A : private B
查看全部 -
//聲明2個類 class?Person { ????public: ????????Person(); ????????~Person(); ????????void?eat(); ????????string?m_strName; ????????int?m_iAge; }; class?Worker:?public?Person { ????public: ????????Worker(); ????????~Worker(); ????????void?work(); ????????int?m_iSalary; }; //定義2個類 Person::Person() ?{ ?????cout<<"Person()"<<endl; ?} Person::~Person() ??{ ??????cout<<"~Person()"<<endl;??? ??} void?eat() { ????cout<<"eat()"<<endl; } ????? ?//定義worker類的函數 ?Worker::Worker() ?{ ?????cout<<"Worker()"<<endl; ?} ? ??Worker::~Worker() ??{ ???cout<<"~Worker()"<<endl; ?? ??} ??void?work() ??{ ???cout<<"work()"<<endl; ??}? ??//應用 ??Worker?*p?=?new?Worker(); ??p->m_strName?=?"jim"; ??p->m_iAge?=?10; ??p->eat(); ??p->m_iSalary?=100; ??p->work(); ??delete?p; ??p?=?NULL; ??//先調用Person,再Worker,析構相反
查看全部 -
什么是繼承,為什么要繼承?
基類----派生類
父類 ----子類
class worker : public person
{
public:
????void work();
????int m_iSalary;
}
//工人類繼承了人類,就不需要重新寫人類的屬性,只寫自己的屬性;工人類是人類的派生類,人類是工人類的基類;人類是父類,工人是子類。
所以派生類和基類是一起組合,父類和子類是一起組合
查看全部 -
沒有虛析構函數的話,繼承后申請的堆內存在釋放時只釋放一次,內存泄漏,虛析構函數,可以完整釋放堆空間
查看全部 -
子類和父類的重名函數無法形成重載,只能進行隱藏
查看全部 -
父類子類變量同名,調用的是子類變量,若調父類變量加作用域
查看全部 -
公有繼承
保護繼承
私有繼承
查看全部 -
公有繼承總結
查看全部
舉報