文章目录
一、继承访问权限测试
1.设计类A具有public, protected, private等不同属性的成员函数或变量;
代码如下:
class A
{
public:
string _name="huanghuali"; //姓名
int _a=10;
protected:
string _sex="girl"; //性别
int _b=101;
private:
int _age=20; //年龄
int _c=102;
};
2.类B通过public, protected, private等不同方式继承A,在类B的成员函数中测试访问A的成员函数或变量;
3.在类B中添加public, protected, private等不同属性的成员函数或变量,在外部测试访问B的各个成员函数或变量;
代码如下:
class B:public A
{
public:
int _No=2019; //学号 B继承了A的姓名,性别,年龄(性别,年龄是私有不可访问)
void Test(){
_a = 10;//ok
_b = 10;//ok
//_c = 10;//error 私有成员不可访问
}
int B_a=10;
protected:
int B_b=101;
private:
int B_c=102;
};
//不可见只能通过基类窗口访问
class B1: protected A
{
public:
void Test(){
_a = 10;//ok
_b = 10;//ok
//_c = 10;//error 不可访问
}
int B1_a=10;
protected:
int B1_b=101;
private:
int B1_c=102;
};
//不可见只能通过基类窗口访问
class B2: private A
{
public:
void Test(){
_a = 10;//ok
_b = 10;//ok
//_c = 10;//error 不可访问
}
int B2_a=10;
protected:
int B2_b=101;
private:
int B2_c=102;
};
int main(){
A a;
std::cout<<a._name<<std::endl;
// std::cout<<a._age<<a._sex<<std::endl; //protected,private不可访问
std::cout<<"calss A_public="<<a._a<<std::endl;
// std::cout<<"calss A_protected="<<a._b<<std::endl;//error
// std::cout<<"calss A_private="<<a._c<<std::endl;//error
B b;
std::cout<<b._name<<b._No<<std::endl;
// std::cout<<b._age<<b._sex<<std::endl;
std::cout<<"calss B_public="<<b.B_a<<std::endl;
// std::cout<<"calss B_protected="<<b.B_b<<std::endl;//error
// std::cout<<"calss B_protected="<<b.B_c<<std::endl;//error
B1 b1;
std::cout<<"calss B1_public="<<b1.B1_a<<std::endl;
// std::cout<<"calss B1_protected="<<b1.B1_b<<std::endl;//error
// std::cout<<"calss B1_protected="<<b1.B1_c<<std::endl;//error
B2 b2;
std::cout<<"calss B2_public="<<b2.B2_a<<std::endl;
// std::cout<<"calss B2_protected="<<b2.B2_b<<std::endl;//error
// std::cout<<"calss B2_protected="<<b2.B2_c<<std::endl;//error
}
测试结果:
B类,B1类,B2类继承了父类A的所有属性。但是因为A类的_c为private类,所以B类,B1类,B2类均不能访问。_b为A类的protected类,可以通过基类窗口访问。
但是在main函数中,我们不可以直接访问A类的private类和protected类的所有属性。
4.B以private方式继承A,尝试把A中的部分public成员提升为public。
代码如下:
//B以private方式继承test_A,尝试把test_A中的部分public成员提升为public
class B3: private A
{
public:
void Test(){
_a = 10;//ok
_b = 10;//ok
//_c = 10;//error 不可访问
}
int B3_a=10;
using A::_a; //用using重新声明。using声明语句中名字的访问权限由该using声明语句之前的访问说明符决定。
using A::_b;
// using A::_c;//error
protected:
int B3_b=101;
private:
int B3_c=102;
};
int main(){
B3 b3;
std::cout<<"calss B3_public="<<b3.B3_a<<std::endl;
std::cout<<"calss A_public="<<b3._a<<std::endl;
std::cout<<"calss A_protected="<<b3._b<<std::endl;
// std::cout<<"calss A_private="<<b3._c<<std::endl;//error
}
测试结果:
用using声明把A类的protected属性转成public正常输出。但是却不能
输出private。
二、友元类继承测试
1.设计类A含有私有变量a,在类A中友元给类C;
代码如下:
//设计类A含有私有变量a,在类A中友元给类C;
class A11
{
private:
int a12=10;
friend class C11;
};
2.设计类B继承A,添加私有变量b;在类C中测试访问类B的成员变量a, b;
代码如下:
//设计类B继承A,添加私有变量b;在类C中测试访问类B的成员变量a, b;
class B11:public A11
{
private:
int b12=11;
};
class C11:public B11
{
void Test(){
A11 a13;
a13.a12; //a为A_类的private,但因为友元函数,所以能访问
std::cout<<"friend:"<<a13.a12<<std::endl;
B11 b13;
// b13.b12; //error
}
};
因为类A11中友元给类C11,所以在测试中能访问A11的private的属性。
友元函数定义:类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。
3.设计类D继承C,在D的成员函数中测试访问类A的成员变量a,类B的成员变量a, b。
代码如下:
//设计类D继承C,在D的成员函数中测试访问类A的成员变量a,类B的成员变量a, b。
class D11:public C11
{
void Test(){
A11 a14;
// a14.a12; //error均为私有,不可访问
B11 b14;
// b14.a12; //error
// b14.b12; //error
}
};
三、多态性综合运用
1.一般多态性函数:输入输出参数完全一样,在父类中添加virtual;
代码如下:
//一般多态性函数:输入输出参数完全一样,在父类中添加virtual;
class CAnimal
{
public:
virtual void Move()
{
std::cout<<"CAnimal Move"<<std::endl;
};
};
class CCat: virtual public CAnimal
{
public:
void Move()
{
std::cout<<"CCat Move"<<std::endl;
};
};
class CEagle:virtual public CAnimal
{
public:
void Move()
{
std::cout<<"CEagle Move"<<std::endl;
};
};
class COwl : public CCat, public CEagle
{
public:
void Move()
{
std::cout<<"COwl Move"<<std::endl;
};
};
int main(){
//一般多态性函数
CAnimal * pA = new CCat();
pA->Move();
CAnimal * pB = new CEagle();
pB->Move();
CCat * pC = new COwl();
pC->Move();
CEagle * pD = new COwl();
pD->Move();
}
测试结果:
2.特殊多态性函数:输入或输出参数在子类中是父类的指针或基类的引用,在子类中对于的是子类的指针或子类的引用;
代码如下:
class CAnimal
{
public:
virtual void Move()
{
std::cout<<"CAnimal Move"<<std::endl;
};
};
class CCat: virtual public CAnimal
{
public:
void Move()
{
std::cout<<"CCat Move"<<std::endl;
};
};
class CEagle:virtual public CAnimal
{
public:
void Move()
{
std::cout<<"CEagle Move"<<std::endl;
};
};
class COwl : public CCat, public CEagle
{
public:
void Move()
{
std::cout<<"COwl Move"<<std::endl;
};
};
//特殊多态性函数:输入或输出参数在子类中是父类的指针或基类的引用,在子类中对于的是子类的指针或子类的引用;
void callMove(CAnimal& an){ //基类的引用
an.Move();
}
void callMove(CAnimal* pAn){ //基类的指针
pAn->Move();
}
int main(){
//特殊多态性函数
CAnimal ca;
callMove(ca);
callMove(&ca);
}
测试结果:
virtual函数:即虚函数是指一个类中你希望重载的成员函数 ,当你用一个基类指针或引用指向一个继承类对象的时候,调用一个虚函数时, 实际调用的是继承类的版本。C++中基类采用virtual虚析构函数是为了防止内存泄漏。
3.析构函数的多态性;
代码如下:
class CAnimal
{
public:
//析构函数的多态性;
~CAnimal()
{
std::cout<<"~CAnimal"<<std::endl;
};
virtual void Move()
{
std::cout<<"CAnimal Move"<<std::endl;
};
};
class CCat: public CAnimal
{
public:
~CCat()
{
std::cout<<"~CCat"<<std::endl;
};
virtual void Move()
{
std::cout<<"CCat Move"<<std::endl;
};
};
class CEagle:virtual public CAnimal
{
public:
~CEagle()
{
std::cout<<"~CEagle"<<std::endl;
};
void Move()
{
std::cout<<"CEagle Move"<<std::endl;
};
};
class COwl : public CCat, public CEagle
{
public:
~COwl()
{
std::cout<<"~COwl"<<std::endl;
};
void Move()
{
std::cout<<"COwl Move"<<std::endl;
};
};
int main(){
CAnimal * pA = new CCat();
pA->~CAnimal();
pA->Move();
CAnimal * pB = new CEagle();
pB->~CAnimal();
pB->Move();
CCat * pC = new COwl();
pC->~CCat();
pC->Move();
CEagle * pD = new COwl();
pD->~CEagle();
pC->Move();
return 0;
}
测试结果: