C++第八節:子類的三大件

子類的三大件

     1.1 子類構造函數中,調用父類構造函數,對來自父類的那部分成員進行初始化,再初始化自己擴展的成員

     1.2 誰的成員,歸誰初始化,子類無需重複完成父類部分的工作

     1.3 父類構造函數放在初始化列表

     1.4 如果在子類的構造函數中,不顯式的調用父類構造函數,將自動調用父類的默認構造函數(前提是有默認構造函數)

     1.5 如果在子類的構造函數內部,調用父類構造函數,會創建一個局部的Base對象,而子類對象自己的成員並沒有被參數初始化

     1.6 析構函數無需參數,在子類的析構函數中,父類的析構函數將被自動調用

     1.7 在拷貝構造函數裏,也是父類成員歸父類初始化

     1.8 構造子類時,先父類後子類;析構子類時,先子類後父類

Base.h
#ifndef __C__No805Class__Base2__
#define __C__No805Class__Base2__

#include <iostream>
#include <string.h>
using namespace std;
class Base2
{
protected:
    int id;
    char *name;
public:
    Base2 (int a = 0, char *s = "A");
    Base2 (const Base2 & b);
    ~Base2();
    const Base2 & operator = (const Base2 & b);
    void print();
};
#endif /* defined(__C__No805Class__Base2__) */
Base.cpp
#include "Base2.h"
Base2::Base2(int a, char * s)
{
    id = a;
    name = new char[strlen(s) + 1];
    strcpy(name, s);
    cout << "Base 默認構造函數" << endl;
}
Base2::Base2(const Base2 & b)
{
    id = b.id;
    name = new char[strlen(b.name) + 1];
    strcpy(name, b.name);
    cout << "Base 拷貝構造函數" << endl;
}
Base2::~Base2()
{
    if(name)
    {
        delete [] name;
        name  = NULL;
    }
    cout << "Base 析構函數" << endl;
}
const Base2 & Base2::operator = (const Base2 & b)
{
    if(this != &b)
    {
        id = b.id;
        delete [] name;
        name = new char[strlen(b.name) + 1];
        strcpy(name, b.name);
    }
    cout << "Base 重載賦值運算符" << endl;
    return *this;
}
void Base2::print()
{
    cout << "Base: id = " << id << " name = " << name <<endl;
}
Derived.h
#ifndef __C__No805Class__Derived2__
#define __C__No805Class__Derived2__

#include <iostream>
#include "Base2.h"
class Derived2 : public Base2
{
private:
    float f;
    char *label;
public:
    Derived2 (int a = 1, char *s = "B", float x = 2, char * t = "C");
    Derived2 (const Derived2 &d);
    ~Derived2();
    const Derived2 & operator = (const Derived2 & d);
    void printD();
};
#endif /* defined(__C__No805Class__Derived2__) */
Derived.cpp
#include "Derived2.h"
//子類構造函數中,調用父類構造函數,對來自父類的那部分成員進行初始化,再初始化自己擴展的成員
//誰的成員,歸誰初始化,子類無需重複完成父類部分的工作
//父類構造函數放在初始化列表
//如果在子類的構造函數中,不顯式的調用父類構造函數,將自動調用父類的默認構造函數(前提是有默認構造函數)
Derived2::Derived2(int a, char * s, float x, char * t) : Base2(a, s)
{
    f = x;
    label = new char[strlen(t) + 1];  //如果在子類的構造函數內部,調用父類構造函數,會創建一個局部的Base對象,而子類對象自己的成員並沒有被參數初始化
    strcpy(label, t);
    cout << "Derived 默認構造函數" << endl;
}
//在拷貝構造函數裏,也是父類成員歸父類初始化
Derived2::Derived2(const Derived2 & d) : Base2(d)
{
    f = d.f;
    label = new char[strlen(d.label) + 1];
    strcpy (label, d.label);
    cout << "Derived 拷貝構造函數" << endl;
}
Derived2::~Derived2()  //析構函數無需參數,在子類的析構函數中,父類的析構函數將被自動調用
{
    if(label)
    {
        delete [] label;
        label = NULL;
    }
    cout << "Derived 析構函數" << endl;
}
const Derived2 & Derived2::operator = (const Derived2 & d)
{
    if(this != &d)
    {
        //調用父類重載的賦值運算符,對子類中父類的成員變量進行賦值
        Base2::operator = (d);
        //再對屬於子類的成員賦值
        f = d.f;
        delete [] label;
        label = new char[strlen(d.label) + 1];
        strcpy(label, d.label);
        cout << "Derived 重載賦值運算符" << endl;
    }
    return *this;
}
void Derived2::printD()
{
    Base2::print();
    cout << "Derived : f = " << f << " label = " << label <<endl;
}
mian.cpp
#include "Derived2.h"
int main()
{
    //構造子類時,先父類後子類(默認、拷貝、重載);析構子類時,先子類後父類
    Derived2 d1;
    d1.printD();
    Derived2 d2(d1);
    d2.printD();
    Derived2 d3;
    d3 = d2;
    d3.printD();
    
    return 0;
}
Father、Son、GrandSon
Father.h
#ifndef __C__No805Class__Father__
#define __C__No805Class__Father__

#include <iostream>
using namespace std;
class Father
{
private:
    char * name;
    int *boys;
    int girls;
public:
    Father(char *n, int *b, int g);
    Father (const Father & f);
    const Father & operator = (const Father & f);
    ~Father();
    void print();
};
#endif /* defined(__C__No805Class__Father__) */
Father.cpp
#include "Father.h"
Father::Father(char *n, int *b, int g)
{
    name = new char[strlen(n) + 1];
    strcpy(name, n);
    boys = new int(*b);
    girls = g;
    cout << "Father構造函數" << endl;
}
Father::Father (const Father & f)
{
    name = new char[strlen(f.name) + 1];
    strcpy(name, f.name);
    boys = new int(*f.boys);
    girls = f.girls;
    cout << "Father拷貝構造函數" <<endl;
}
const Father & Father::operator = (const Father & f)
{
    if(this != &f)
    {
        delete boys;
        delete [] name;
        name = new char[strlen(f.name) + 1];
        strcpy(name, f.name);
        boys = new int(*f.boys);
        girls = f.girls;
    }
    cout << "Father重載賦值運算符" << endl;
    return *this;
}
Father::~Father()
{
    if(boys)
    {
        delete boys;
        boys = NULL;
    }
    if(name)
    {
        delete []name;
        name = NULL;
    }
    cout << "析構Father" << endl;
}
void Father::print()
{
    cout << "Father part: name:" << name << " boys:" << *boys << " girls:" << girls << endl;
}
Son.h
#ifndef __C__No805Class__Son__
#define __C__No805Class__Son__

#include <iostream>
#include "Father.h"
class Son : public Father
{
private:
    char *address;
    int *girlFirends;
    double score;
public:
    Son(char *n, int *b, int g, char* a, int *gf, double s);
    Son (const Son & s);
    const Son & operator = (const Son & s);
    ~Son();
    void print();
};
#endif /* defined(__C__No805Class__Son__) */
Son.cpp
#include "Son.h"
Son::Son(char *n, int *b, int g, char* a, int *gf, double s) : Father(n, b, g)
{
    address = new char[strlen(a) + 1];
    strcpy (address, a);
    girlFirends = new int(*gf);
    score = s;
    cout << "Son構造函數" <<endl;
}
Son::Son (const Son & s) : Father(s)
{
    address = new char[strlen(s.address) + 1];
    strcpy (address, s.address);
    girlFirends = new int(*s.girlFirends);
    score = s.score;
    cout << "Son拷貝構造函數" << endl;
}
const Son & Son::operator = (const Son & s)
{
    if(this != &s)
    {
        Father::operator=(s);
        delete [] address;
        address = new char[strlen(s.address) + 1];
        strcpy (address, s.address);
        delete girlFirends;
        girlFirends = new int(*s.girlFirends);
        score = s.score;
    }
    cout << "Son重載賦值運算符" << endl;
    return *this;
}
Son::~Son()
{
    if(address)
    {
        delete [] address;
        address = NULL;
    }
    if(girlFirends)
    {
        delete girlFirends;
        girlFirends = NULL;
    }
    cout << "析構Son" << endl;
}
void Son::print()
{
    Father::print();
    cout << "Son part: address:" << address << " girlFriends:" << *girlFirends << " score:" << score << endl;
}
GrandSon.h
#ifndef __C__No805Class__GrandSon__
#define __C__No805Class__GrandSon__

#include <iostream>
#include "Son.h"
class GrandSon : public Son
{
private:
    char *description;
    int sons;
public:
    GrandSon(char *n, int *b, int g, char* a, int *gf, double s, char *d, int son);
    GrandSon (const GrandSon & g);
    const GrandSon & operator = (const GrandSon & g);
    ~GrandSon();
    void print();
};
#endif /* defined(__C__No805Class__GrandSon__) */
GrandSon.cpp
#include "GrandSon.h"
GrandSon::GrandSon(char *n, int *b, int g, char* a, int *gf, double s, char *d, int son) : Son(n, b, g, a, gf, s)
{
    description = new char[strlen(d) + 1];
    strcpy (description, d);
    sons = son;
    cout << "GrandSon構造函數" << endl;
}
GrandSon::GrandSon (const GrandSon & g) : Son(g)
{
    description = new char[strlen(g.description) + 1];
    strcpy (description, g.description);
    sons = g.sons;
    cout << "GrandSon拷貝構造函數" << endl;
}
const GrandSon & GrandSon::operator = (const GrandSon & g)
{
    if (this != &g)
    {
        Son::operator = (g);
        delete [] description;
        description = new char[strlen(g.description) + 1];
        strcpy (description, g.description);
        sons = g.sons;
    }
    cout << "GrandSon重載賦值運算符" << endl;
    return *this;
}
GrandSon::~GrandSon()
{
    if (description)
    {
        delete [] description;
        description = NULL;
    }
    cout << "析構GrandSon" << endl;
}
void GrandSon::print()
{
    Son::print();
    cout << "GrandSon part: description:" << description << " sons:" << sons << endl;
}
main.cpp
#include "GrandSon.h"
int main()
{
    int b = 2, gf = 1;
    Father f1("ABC", &b, 2);
    f1.print();
    Father f2(f1);
    f2.print();
    Father f3("DEF", &b, 3);
    f3.print();
    f3 = f1;
    f3.print();
    
    Son s1("ABC", &b, 2, "北京", &gf, 88);
    s1.print();
    Son s2(s1);
    s2.print();
    Son s3("DEF", &b, 3, "河南", &gf, 99);
    s3.print();
    s3 = s1;
    s3.print();
    
    GrandSon g1("ABC", &b, 2, "北京", &gf, 88, "粉粉的", 2);
    g1.print();
    GrandSon g2(g1);
    g2.print();
    GrandSon g3("DEF", &b, 3, "河南", &gf, 99, "白白的", 3);
    g3.print();
    g3 = g1;
    g3.print();
    
    return 0;
}

發佈了31 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章