
目录
实验内容
一、继承访问
1.设计类A具有public, protected, private等不同属性的成员函数或变量;
2.在类B中添加public, protected, private等不同属性的成员函数或变量;类B通过public, protected, private等不同方式继承A,在类B的成员函数中测试访问A的成员函数或变量:
2.1类B通过public方式继承A,测试访问A的成员函数或变量:
2.2类B通过protected方式继承A,测试访问A的成员函数或变量:
2.3类B通过private方式继承A,测试访问A的成员函数或变量:
3.B以private方式继承A,尝试把A中的部分public成员提升为public。
继承类总结:
二、友元类继承
1.设计类A含有私有变量a,在类A中友元给类C;
2.设计类B继承A,添加私有变量b;在类C中测试访问类B的成员变量a, b;
3.设计类D继承C,在D的成员函数中测试访问类A的成员变量a,类B的成员变量a, b。
三.多态性综合运用
1.一般多态性函数:输入输出参数完全一样,在父类中添加virtual;
2.特殊多态性函数:输入或输出参数在子类中是父类的指针或基类的引用,在子类中对于的是子类的指针或子类的引用:
3.析构函数的多态性:
4.虚继承:
总结:
实验内容
一、继承访问权限测试
设计类A具有public, protected, private等不同属性的成员函数或变量;
类B通过public, protected, private等不同方式继承A,在类B的成员函数中测试访问A的成员函数或变量;
在类B中添加public, protected, private等不同属性的成员函数或变量,在外部测试访问B的各个成员函数或变量;
B以private方式继承A,尝试把A中的部分public成员提升为public。
二、友元类继承测试
设计类A含有私有变量a,在类A中友元给类C;
设计类B继承A,添加私有变量b;在类C中测试访问类B的成员变量a, b;
设计类D继承C,在D的成员函数中测试访问类A的成员变量a,类B的成员变量a, b。
三、多态性综合运用
一般多态性函数:输入输出参数完全一样,在父类中添加virtual;
特殊多态性函数:输入或输出参数在子类中是父类的指针或基类的引用,在子类中对于的是子类的指针或子类的引用;
析构函数的多态性;
多继承,注意什么情况需要虚继承;
设计矢量图,运用多继承设计组合图形,要求具备创建不同类型矢量图、选择图形、移动图形、用不同颜色显示图形(表示选中与否),用vector或数组管理图形。
一、继承访问 1.设计类A具有public, protected, private等不同属性的成员函数或变量;
class Person //A类
{
public: //公有函数成员
string m_strName; //姓名
Person();
virtual ~Person();
Person(string strName,string strSex,int Age);
void SetSex(string strSex)
{
m_strSex = strSex;
}
protected: //保护数据成员
string m_strSex; //性别
private: //私有数据成员
int m_nAge; //年龄
};
2.在类B中添加public, protected, private等不同属性的成员函数或变量;类B通过public, protected, private等不同方式继承A,在类B的成员函数中测试访问A的成员函数或变量:
2.1类B通过public方式继承A,测试访问A的成员函数或变量:
class Student: public Person //B类继承A类
{
public:
Student();
~Student();
void SetType();
void SetName(string strName="") //隐含的内联函数
{
m_strName = strName; //student通过public继承Person在类的内部可以访问
}
void SetSex(string strSex="")
{
m_strSex = strSex; public方式继承父类protect变量可以访问
}
void SetAge(int Age)
{
//m_nAge = Age; //public继承方式不能访问private变量
}
inline string GetSex();
protected:
double m_nNumber; //学生成绩
private:
string m_nScore; //学生学号
};
void TestPerson()
{
Person per;
per.m_strName = "tjw";
//per.m_strSex = ""; //父类Person的protected属性在外部无法访问
//per.m_nAge = 0; //父类private属性在外部也无法访问
Student stu;
stu.m_strName = "tjw";
//stu.m_strSex = "man"; //public继承下,父类的protected属性同样无法在外部被子类访问
//stu.m_nAge = 0; //public继承下,父类的private属性无法在外部被子类访问
}
2.2类B通过protected方式继承A,测试访问A的成员函数或变量:
class Worker:protected Person
{
public:
void SetName(string strName="")
{
m_strName = strName; //Worker通过protected继承Person在类的内部可以访问
}
void SetSex(string strSex="")
{
m_strSex = strSex; //父类protected属性用protected继承也可以访问
}
void SetAge(int Age)
{
//m_nAge = Age; //protected继承方式不能访问private变量
}
string & GetName()
{
return m_strName;
}
};
//使用protected来继承的话,原有自由度高于protected的变量都会被降级成protected
void TestPerson()
{
Worker worker;
worker.SetName("zzz");//protected变量在外部无法被访问,该行代码无法运行
worker.m_strName="";//protected变量无法在外部函数中被访问
worker.m_strSex ="man";//private变量无法在外部函数中被访问
}
2.3类B通过private方式继承A,测试访问A的成员函数或变量:
class Teacher:private Person
{
public:
void SetName(string strName="")
{
m_strName = strName; //Teacher类通过private继承Person在类的内部可以访问
}
void SetSex(string strSex="")
{
m_strSex = strSex; //父类protected属性用private继承也可以访问
}
void SetAge(int Age)
{
//m_nAge = Age; //private继承方式不能访问private变量
}
};
//使用private来继承父类,原有权限高于private的变量都会被降成private
void TestPerson()
{
Teacher teacher;
teacher.m_strName = "";//private变量无法在外部函数中被访问
teacher.m_strSex = "";//private变量无法在外部函数中被访问
teacher.m_nAge = 0;//private变量无法在外部函数中被访问
}
3.B以private方式继承A,尝试把A中的部分public成员提升为public。
class Teacher:private Person
{
public:
using Person::m_strName;
using Person::m_strSex; //将基类的protected变量变为public访问级别
using Person::m_nAge;
string & GetName()
{
return m_strName;
}
void SetName(string strName="")
{
m_strName = strName; //Teacher类通过private继承Person在类的内部可以访问
}
void SetSex(string strSex="")
{
m_strSex = strSex; //父类protected属性用private继承也可以访问
}
void SetAge(int Age)
{
//m_nAge = Age; //private继承方式不能访问private变量
}
};
void TestPerson()
{
Teacher teacher;
//用protected,private继承的不能被外部访问,可以用using提升访问权限到public
teacher.m_strName = "";
teacher.m_strSex = "";
//若不用using提升访问权限,则父类public,protected,private的变量均无法访问
}
继承类总结:
1.继承类只能访问父类protected级以上的变量或成员函数,不能访问private
2.用protected,private继承的不能被外部访问,可以用using提升访问权限到public进而访问;
二、友元类继承 1.设计类A含有私有变量a,在类A中友元给类C;class Person //A类
{
public: //公有函数成员
string m_strName; //姓名
Person();
Person(string strName,string strSex,int Age);
void SetSex(string strSex)
{
m_strSex = strSex;
}
friend class Teacher; //将Teacher类设置成Person类的友元类,使其子类所有函数均可访问父类成员
friend void A::TestFriend(Person &per); //友元成员函数,只允许TestFriend()访问私有量
//友元成员函数:在类A的内部声明一个属于类B的成员函数,则只有该成员才能访问类A的私有成员
friend void TestFriendFun(Person &per) //友元函数(全局),同样可以访问私有变量(第一种实现方式:实现过程在类的内部)
{
per.m_nAge =20;
}
friend void TestFriendFun(Person &per); //第二种实现方式:实现过程在类的外部
friend istream & operator>>(istream &is,Person &per);
friend ostream & operator<<(ostream &os,const Person &person);
bool Create(string strName,string strSex,int Age);
protected: //保护数据成员
string m_strSex; //性别
private: //私有数据成员
int m_nAge; //年龄 即a
};
2.设计类B继承A,添加私有变量b;在类C中测试访问类B的成员变量a, b;
class Student:public Person //B
{
public:
~ Student();
void Person_Career(Person& p);
void Student_Career(Student& p);
void returnCareer();
using Person::m_strSex;
using Person::m_strName;
//使用这两行代码可以将因为继承方式采用private而导致sex和name两个属性改为public公开
Student();
string m_nSubject;
void SetSex(string strSex="")
{
m_strSex = strSex;//内部函数可以访问protected变量,外部不行
}//隐藏内联函数
private:
double m_nScore; //考试分数 即b
protected:
string m_nNumber; //学生学号
inline string GetSex(); //显示内联函数
};
3.设计类D继承C,在D的成员函数中测试访问类A的成员变量a,类B的成员变量a, b。
class D:protected Teacher //D
{
public:
Person person;
Student student;
void visit() {
//person.m_nAge = 1; //类A的成员变量a无法访问
//student.m_nAge = 2; //类B的成员变量a无法访问
//student.m_nScore = 1; //类B的成员变量b无法访问
}
};
三.多态性综合运用 1.一般多态性函数:输入输出参数完全一样,在父类中添加virtual;
通过使用virtual关键字对多态进行支持,被virtual声明的函数被重写后具有多态特性,被virtual声明的函数叫做虚函数
class Person //A类
{
public: //公有函数成员
string m_strName; //姓名
Person();
virtual ~Person();
Person(string strName,string strSex,int Age);
virtual void SetType();
//virtual void SetWork() =0; //纯虚函数
void SetSex(string strSex)
{
m_strSex = strSex;
}
friend class Teacher; //将Teacher类设置成Person类的友元类,使其子类所有函数均可访问父类成员
friend void A::TestFriend(Person &per); //友元成员函数,只允许TestFriend()访问私有变量
//友元成员函数:在类A的内部声明一个属于类B的成员函数,则只有该成员才能访问类A的私有成员
friend void TestFriendFun(Person &per) //友元函数(全局),同样可以访问私有变量(第一种实现方式:实现过程在类的内部)
{
per.m_nAge =20;
}
friend void TestFriendFun(Person &per); //第二种实现方式:实现过程在类的外部
friend istream & operator>>(istream &is,Person &per);
friend ostream & operator<<(ostream &os,const Person &person);
bool Create(string strName,string strSex,int Age);
protected: //保护数据成员
string m_strSex; //性别
private: //私有数据成员
int m_nAge; //年龄
};
int main(int argc, char *argv[])
{
Person *stu = new Student(); //基类使用派生类的构造器,基类类型的指针指向派生类对象
stu->SetType(); //使用基类和派生类都实现的setType()函数测试真正调用的是哪一个
return 0;
}
运行结果:
结果说明了当使用虚函数继承机制的时候,会调用派生类中的函数,而不是基类。
2.特殊多态性函数:输入或输出参数在子类中是父类的指针或基类的引用,在子类中对于的是子类的指针或子类的引用:void TestType(Person *p) //传入的是基类的指针
{
p->SetType();
}
void TestType(Person &p) //传入的是基类的引用
{
p.SetType();
}
int main(int argc, char *argv[])
{
Person *stu = new Student(); //基类使用派生类的构造器,基类类型的指针指向派生类对象
stu->SetType(); //使用基类和派生类都实现的setType()函数测试真正调用的是哪一个
Person p1;
Student s1;
//TestType(p1);//调用void TestType(Person *p)
//TestType(s1); //调用void TestType(Person *p)
TestType(&p1); //调用void TestType(Person *p)
TestType(&s1);//调用void TestType(Person *p)
return 0;
}
运行结果:
3.析构函数的多态性:类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
//析构函数
Person::~Person()
{
cout<<"delete Person!"<
运行结果:
4.虚继承:
在多重继承中,如果发生了如:类B继承类A,类C继承类A,类D同时继承了类B和类C。最终在类D中就有了两份类A的成员,如下图:
这在程序中是不能容忍的。当然解决这个问题的方法就是利用虚继承。
虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。其中,这个被共享的基类就称为虚基类(Virtual base Class),本例中的 A 就是一个虚基类。在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。因为在虚继承的最终派生类中只保留了一份虚基类的成员,所以该成员可以被直接访问,不会产生二义性。
class B: virtual public A{ //在基类前加virtual虚继承
protected:
int m_b;
};
总结:
在本次实验中,我进行了继承权限访问测试,友元类继承测试,多态性综合运用,初步学会了虚继承,用using语句提升继承的部分权限,友元类继承的相关概念和具体如何使用虚函数来实现函数多态性。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)