子類的三大件
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#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;
}