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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值