目录
1. 派生类定义
2. 派生类的访问控制、构造、同名覆盖、多态性、虚函数、多继承、虚继承
3. 派生类对象的克隆
4. 典型范例——各类物体面积求和
5. 其他继承方式
5.1 私有继承和保护继承
1. 派生类定义
class 派生类名:public 基类名
{
public:
派生类公有函数成员
private:
派生类私有函数成员
private:
派生类私有数据成员
};
2. 派生类的访问控制、构造、同名覆盖、多态性、虚函数、多继承、虚继承
- protected访问控制专用于继承和派生,protected修饰的成员是保护成员
#include
#include
#include
using namespace std;
class CPerson
{
public:
CPerson(string Name, int Age) :m_Name(Name), m_Age(Age) {}
void SetName(string Name)
{
m_Name = Name;
}
void SetAge(int Age)
{
m_Age = Age;
}
const string& GetName()const
{
return m_Name;
}
int GetAge()const
{
return m_Age;
}
void Show()const
{
cout << m_Name << ',' << m_Age << "years old. " << endl;
}
protected:
string m_Name;
int m_Age;
};
class CStudent :public CPerson
{
public:
CStudent(string Name, int Age) :CPerson(Name, Age) {}
void Show()const; //同名覆盖原则
void StudyCourse(string strCourse);
void ShowAllStudyCourse()const;
private:
vector m_strVec;
};
void CStudent::Show()const
{
CPerson::Show();
cout << "A student" << endl;
}
void CStudent::StudyCourse(string strCourse)
{
this->m_strVec.push_back(strCourse);
}
void CStudent::ShowAllStudyCourse()const
{
cout << m_Name << "nStudent's draft courses list:" << endl;
for (size_t i = 0; i < m_strVec.size(); i++)
{
cout << m_strVec[i] << endl;
}
cout << endl;
}
class CTeacher:virtual public CPerson // virtual是虚继承,避免出现多义性问题
{
public:
CTeacher(string Name, int Age) :CPerson(Name, Age) {}
void Show()const;
void TeacherCourse(string strCourse);
void ShowAllTeacherCourse()const;
private:
vector m_strVec;
};
void CTeacher::Show()const
{
CPerson::Show();
cout << "A teacher" << endl;
}
void CTeacher::TeacherCourse(string strCourse)
{
this->m_strVec.push_back(strCourse);
}
void CTeacher::ShowAllTeacherCourse()const
{
cout << m_Name << "nList of courses taugh by teacher:" << endl;
for (size_t i = 0; i < m_strVec.size(); i++)
{
cout << m_strVec[i] << endl;
}
cout << endl;
}
class CGraduate :virtual public CPerson
{
public:
CGraduate(string Name, int Age) :CPerson(Name, Age) {}
void Show()const;
void StudentCourse(string strCourse);
void ShowAllStudyCourse()const;
private:
vector m_strVec;
};
void CGraduate::Show()const
{
CPerson::Show();
cout << "A student" << endl;
}
void CGraduate::StudentCourse(string strCourse)
{
this->m_strVec.push_back(strCourse);
}
void CGraduate::ShowAllStudyCourse()const
{
cout << m_Name << endl << "nStudent's draft courses list:" << endl;
for (size_t i = 0; i < m_strVec.size(); i++)
{
cout << m_strVec[i] << endl;
}
cout << endl;
}
class CGraduateTeacher :public CTeacher, public CGraduate
{
public:
CGraduateTeacher(string Name, int Age) :
CPerson(Name, Age), CTeacher(Name, Age), CGraduate(Name, Age) {}
void Show()const;
};
void CGraduateTeacher::Show()const
{
CPerson::Show();
cout << "A Graduate teachern";
}
void ShowByPointer(CPerson* pPerson) //虚函数
{
pPerson->Show();
}
void ShowByReference(CPerson& person)
{
person.Show();
}
void ShowByValue(CPerson person)
{
person.Show();
}
int main()
{
CStudent zhang("张三丰", 20);
CStudent wang("王阳明", 21);
CTeacher Li("梨落", 32);
CGraduate Cao("曹梦洁", 20);
CGraduateTeacher Hong("洪嘉玉", 22);
zhang.StudyCourse("程序设计基础");
zhang.StudyCourse("C++程序设计");
zhang.StudyCourse("数据结构");
wang.StudyCourse("数学");
wang.StudyCourse("英语");
wang.StudyCourse("物理");
Li.TeacherCourse("数字电路");
Li.TeacherCourse("计算机组成原理");
zhang.ShowAllStudyCourse();
wang.ShowAllStudyCourse();
Li.ShowAllTeacherCourse();
cout << endl;
zhang.Show();
wang.Show();
Li.Show();
cout << endl;
ShowByPointer(&zhang);
ShowByPointer(&wang);
ShowByPointer(&Li);
cout << endl;
ShowByReference(zhang);
ShowByReference(wang);
ShowByReference(Li);
cout << endl;
ShowByValue(zhang);
ShowByValue(wang);
ShowByValue(Li);
cout << endl;
Cao.Show();
Hong.Show();
return 0;
}
3. 派生类对象的克隆
#include
#include
#include
using namespace std;
class CMammal;
vector zoo;
class CMammal
{
public:
CMammal(string name, int age) :m_name(name), m_age(age)
{
zoo.push_back(this);
}
virtual CMammal* Clone()const = 0;
void Show()const;
protected:
string m_name;
int m_age;
};
void CMammal::Show()const
{
cout << m_name << " age: " << m_age << endl;
}
void ShowAllAnimal()
{
for (size_t i = 0; i < zoo.size(); i++)
{
zoo[i]->Show();
}
cout << endl;
}
class CDog :public CMammal
{
public:
CMammal* Clone()const
{
return new CDog(*this); //调用拷贝构造动态生成一只狗
}
CDog(string name, int age) : CMammal(name, age) {}
};
class CHorse : public CMammal
{
public:
CMammal* Clone()const
{
return new CHorse(*this);
}
CHorse(string name, int age) :CMammal(name, age) {}
};
int main()
{
CDog a("恭喜", 12);
CDog b("发财", 11);
CHorse c("赤兔", 8);
CHorse d("的卢", 10);
size_t n = zoo.size(); //原动物数量
for (size_t i = 0; i < n; i++)
{
zoo.push_back(zoo[i]->Clone()); //克隆原动物,放入zoo中
}
ShowAllAnimal();
return 0;
}
4. 典型范例——各类物体面积求和
#include
#include
#include
#include
#include
using namespace std;
const double PI = 3.1416;
class CShape
{
public:
virtual double GetArea()const = 0;
};
class CCircle :public CShape
{
public:
CCircle(double radius) :m_radius(radius) {}
virtual double GetArea()const;
private:
double m_radius;
};
double CCircle::GetArea()const
{
return PI * m_radius * m_radius;
}
class CTriangle : public CShape
{
public:
CTriangle(double a, double b, double c) :m_a(a), m_b(b), m_c(c) {}
virtual double GetArea()const;
private:
double m_a, m_b, m_c;
};
double CTriangle::GetArea()const
{
return sqrt((m_a + m_b + m_c) *
(m_a + m_b - m_c) *
(m_a + m_c - m_b) *
(m_b + m_c - m_a)) / 4.0;
}
class CRectangle :public CShape
{
public:
CRectangle(double length, double width) :m_length(length), m_width(width) {}
virtual double GetArea()const;
private:
double m_length, m_width;
};
double CRectangle::GetArea()const
{
return m_length * m_width;
}
double TotalArea(const vector& vecShapes)
{
double dSum = 0;
for (unsigned int i = 0; i < vecShapes.size(); i++)
{
dSum += vecShapes[i]->GetArea();
}
return dSum;
}
int main()
{
vector vecShapes;
string strShape;
while (cin >> strShape)
{
if (strShape == "circle")
{
double radius;
cin >> radius;
vecShapes.push_back(new CCircle(radius));
}
else if (strShape == "triangle")
{
double a, b, c;
cin >> a >> b >> c;
vecShapes.push_back(new CTriangle(a, b, c));
}
else if (strShape == "rectangle")
{
double length, width;
cin >> length >> width;
vecShapes.push_back(new CRectangle(length, width));
}
}
cout << fixed << setprecision(4) << TotalArea(vecShapes) << endl;
for (unsigned int i = 0; i < vecShapes.size(); i++)
{
delete vecShapes[i];
}
return 0;
}
5. 其他继承方式
5.1 私有继承和保护继承
class 派生类名 :private 基类名
{
... //私有继承
}
class 派生类名 :protected 基类名
{
... //保护继承
}
- 私有继承后,基类公有成员和保护成员在派生类里成为了私有成员,也就是派生类对象不再具有基类对象所具有的功能,派生类对象不再是一种基类对象,不符合赋值兼容原则。
- 保护继承后,基类公有成员和保护成员在派生类里成为了保护成员,派生类对象不再具有基类对象所具有的功能,派生类对象不再是一种基类对象,也不符合赋值兼容原则。
#include
#include
using namespace std;
class CStack :private list
{
public:
void push(int x);
bool empty()const;
int top()const;
void pop();
};
void CStack::push(int x)
{
this->push_back(x);
}
bool CStack::empty()const
{
return (list::empty());
}
int CStack::top()const
{
return this->back();
}
void CStack::pop()
{
this->pop_back();
}
int main()
{
CStack S1, S2;
int v, x;
while (cin >> v >> x)
{
if (v == 1)
{
S1.push(x);
}
else
{
S2.push(x);
}
}
while (!S1.empty())
{
x = S1.top();
cout << x << ' ';
S1.pop();
}
cout << endl;
while (!S2.empty())
{
x = S2.top();
cout << x << ' ';
S2.pop();
}
cout << endl;
return 0;
}
#include#include #include using namespace std; class CMammal; vector zoo; class CMammal { public: CMammal(string name, int age) :m_name(name), m_age(age) { zoo.push_back(this); } virtual CMammal* Clone()const = 0; void Show()const; protected: string m_name; int m_age; }; void CMammal::Show()const { cout << m_name << " age: " << m_age << endl; } void ShowAllAnimal() { for (size_t i = 0; i < zoo.size(); i++) { zoo[i]->Show(); } cout << endl; } class CDog :public CMammal { public: CMammal* Clone()const { return new CDog(*this); //调用拷贝构造动态生成一只狗 } CDog(string name, int age) : CMammal(name, age) {} }; class CHorse : public CMammal { public: CMammal* Clone()const { return new CHorse(*this); } CHorse(string name, int age) :CMammal(name, age) {} }; int main() { CDog a("恭喜", 12); CDog b("发财", 11); CHorse c("赤兔", 8); CHorse d("的卢", 10); size_t n = zoo.size(); //原动物数量 for (size_t i = 0; i < n; i++) { zoo.push_back(zoo[i]->Clone()); //克隆原动物,放入zoo中 } ShowAllAnimal(); return 0; }
4. 典型范例——各类物体面积求和
#include
#include
#include
#include
#include
using namespace std;
const double PI = 3.1416;
class CShape
{
public:
virtual double GetArea()const = 0;
};
class CCircle :public CShape
{
public:
CCircle(double radius) :m_radius(radius) {}
virtual double GetArea()const;
private:
double m_radius;
};
double CCircle::GetArea()const
{
return PI * m_radius * m_radius;
}
class CTriangle : public CShape
{
public:
CTriangle(double a, double b, double c) :m_a(a), m_b(b), m_c(c) {}
virtual double GetArea()const;
private:
double m_a, m_b, m_c;
};
double CTriangle::GetArea()const
{
return sqrt((m_a + m_b + m_c) *
(m_a + m_b - m_c) *
(m_a + m_c - m_b) *
(m_b + m_c - m_a)) / 4.0;
}
class CRectangle :public CShape
{
public:
CRectangle(double length, double width) :m_length(length), m_width(width) {}
virtual double GetArea()const;
private:
double m_length, m_width;
};
double CRectangle::GetArea()const
{
return m_length * m_width;
}
double TotalArea(const vector& vecShapes)
{
double dSum = 0;
for (unsigned int i = 0; i < vecShapes.size(); i++)
{
dSum += vecShapes[i]->GetArea();
}
return dSum;
}
int main()
{
vector vecShapes;
string strShape;
while (cin >> strShape)
{
if (strShape == "circle")
{
double radius;
cin >> radius;
vecShapes.push_back(new CCircle(radius));
}
else if (strShape == "triangle")
{
double a, b, c;
cin >> a >> b >> c;
vecShapes.push_back(new CTriangle(a, b, c));
}
else if (strShape == "rectangle")
{
double length, width;
cin >> length >> width;
vecShapes.push_back(new CRectangle(length, width));
}
}
cout << fixed << setprecision(4) << TotalArea(vecShapes) << endl;
for (unsigned int i = 0; i < vecShapes.size(); i++)
{
delete vecShapes[i];
}
return 0;
}
5. 其他继承方式
5.1 私有继承和保护继承
class 派生类名 :private 基类名
{
... //私有继承
}
class 派生类名 :protected 基类名
{
... //保护继承
}
- 私有继承后,基类公有成员和保护成员在派生类里成为了私有成员,也就是派生类对象不再具有基类对象所具有的功能,派生类对象不再是一种基类对象,不符合赋值兼容原则。
- 保护继承后,基类公有成员和保护成员在派生类里成为了保护成员,派生类对象不再具有基类对象所具有的功能,派生类对象不再是一种基类对象,也不符合赋值兼容原则。
#include
#include
using namespace std;
class CStack :private list
{
public:
void push(int x);
bool empty()const;
int top()const;
void pop();
};
void CStack::push(int x)
{
this->push_back(x);
}
bool CStack::empty()const
{
return (list::empty());
}
int CStack::top()const
{
return this->back();
}
void CStack::pop()
{
this->pop_back();
}
int main()
{
CStack S1, S2;
int v, x;
while (cin >> v >> x)
{
if (v == 1)
{
S1.push(x);
}
else
{
S2.push(x);
}
}
while (!S1.empty())
{
x = S1.top();
cout << x << ' ';
S1.pop();
}
cout << endl;
while (!S2.empty())
{
x = S2.top();
cout << x << ' ';
S2.pop();
}
cout << endl;
return 0;
}
5.1 私有继承和保护继承
class 派生类名 :private 基类名
{
... //私有继承
}
class 派生类名 :protected 基类名
{
... //保护继承
}
- 私有继承后,基类公有成员和保护成员在派生类里成为了私有成员,也就是派生类对象不再具有基类对象所具有的功能,派生类对象不再是一种基类对象,不符合赋值兼容原则。
- 保护继承后,基类公有成员和保护成员在派生类里成为了保护成员,派生类对象不再具有基类对象所具有的功能,派生类对象不再是一种基类对象,也不符合赋值兼容原则。
#include
#include
using namespace std;
class CStack :private list
{
public:
void push(int x);
bool empty()const;
int top()const;
void pop();
};
void CStack::push(int x)
{
this->push_back(x);
}
bool CStack::empty()const
{
return (list::empty());
}
int CStack::top()const
{
return this->back();
}
void CStack::pop()
{
this->pop_back();
}
int main()
{
CStack S1, S2;
int v, x;
while (cin >> v >> x)
{
if (v == 1)
{
S1.push(x);
}
else
{
S2.push(x);
}
}
while (!S1.empty())
{
x = S1.top();
cout << x << ' ';
S1.pop();
}
cout << endl;
while (!S2.empty())
{
x = S2.top();
cout << x << ' ';
S2.pop();
}
cout << endl;
return 0;
}
-
using namespace std;
class CStack :private list



