<1>必备知识
私密程度: public < protected < private
public:无访问限制可以被任何地方访问,包括类的内部、外部、类的派生类以及类的成员函数。
protected:较为开放,可以被该类的成员函数、友元 和 派生类的成员函数访问。
private:只允许该类的成员函数和友元访问,不允许派生类访问。
举例说明:
创建了一个Students类,内部有public,protected,private三种类型的成员
class Student
{
public:
std::string pub_name;
short pub_age;
std::string pub_gantal;
protected:
long pro_sno;
private:
long pri_phonenumber;
std::string pri_address;
public:
void initPubInfo(std::string pub_name,short pub_age,std::string pub_gantal)
{
this->pub_name = pub_name;
this->pub_age = pub_age;
this->pub_gantal = pub_gantal;
}
void showPubInfo()
{
std::cout<<"name: "<<this->pub_name<<","
<<"age: "<<this->pub_age<<","
<<"gental: "<<this->pub_gantal<<std::endl;
}
void initProInfo(long pro_sno)
{
this->pro_sno = pro_sno;
}
void showProInfo()
{
std::cout<<"student's sno: "<<this->pro_sno<<std::endl;
}
void initPriInfo(long pri_phonenumber,std::string pri_address)
{
this->pri_phonenumber = pri_phonenumber;
this->pri_address = pri_address;
}
void showPriInfo()
{
std::cout<<"phone number: "<<this->pri_phonenumber<<","
<<"address: "<<this->pri_address<<std::endl;
}
};
(1)三者均可被该类的成员函数访问:
1.首先验证public类型成员:
Student* student = new Student();
student->initPubInfo("Jack",24,"男");
student->showPubInfo();
控制台输出:
public成员还能在任何地方被修改,调用:
Student* student = new Student();
student->pub_age=24;
student->pub_gantal="女";
student->pub_name="Jack";
std::cout<<student->pub_age<<","
<<student->pub_gantal<<","
<<student->pub_name<<std::endl;
控制台输出:
验证成功!
2.验证protected:
Student* student = new Student();
student->initProInfo(2024854);
student->showProInfo();
控制台输出:
成功验证其能被该类的成员函数访问!
3.验证private:
Student* student= new Student();
student->initPriInfo(18392893222,"ShangHai");
student->showPriInfo();
控制台输出:
成功验证其能被该类的成员函数访问!
(2)验证私密性
protected与private成员均不能在类外部被访问:
软件界面未给出我们选择protected与privated成员的访问选项,强行访问会导致编译器报错!只给出了public成员的访问选项,验证成功!
(3)验证派生类是否可以访问
创建派生类:Entity
class Entity : public Student
{
public:
void Doing()
{
}
}
(或许有的小伙伴会存有疑问,为什么时public Student,而不是protected Student ,private Student,这里做出解释:
在 C++ 中,继承是通过指定继承类型来控制基类成员的访问权限。public
, protected
, 和 private
这三种继承方式各自有不同的行为,它们会影响基类成员在派生类中的访问权限。具体来说,使用 public Student
而不是 protected Student
或 private Student
的原因如下:
1. public
继承
- 访问权限:基类的
public
成员在派生类中仍然是public
,而基类的protected
成员在派生类中仍然是protected
,基类的private
成员依然无法访问。 - 外部访问:通过
public
继承,基类的public
成员对所有使用派生类对象的外部代码都是可访问的。这意味着可以直接使用派生类对象访问基类的public
成员。
2. protected
继承
- 访问权限:基类的
public
成员在派生类中变为protected
,这意味着外部代码无法直接访问它们。只有通过派生类的成员函数才能访问这些成员。 - 外部访问:通过
protected
继承,派生类对象的外部代码无法直接访问基类的public
成员。
3. private
继承
- 访问权限:基类的所有成员(无论是
public
还是protected
)在派生类中都变为private
,这意味着外部代码无法访问这些成员。 - 外部访问:通过
private
继承,派生类对象的外部代码完全无法访问基类的成员,包括public
和protected
成员。
)
预在派生类中访问Student类中成员时,只提供了public与protected成员选项,强行访问private成员会报错!
得出结论private成员无法在派生类中被调用!
(4)验证友元函数
概念:
友元函数是一种可以访问类的私有和保护成员的非成员函数。虽然它不是类的成员,但由于使用了 friend
关键字,类授予了它访问私有和保护成员的权限。
特点:
- 友元函数并不属于类的成员,因此不能通过对象直接调用,需要通过常规的函数调用方式使用。
- 友元函数的声明在类的内部,定义可以在类的外部。
- 友元函数可以是全局函数、其他类的成员函数,甚至是静态函数。
在Student类中声明友元函数,可在类内部声明,类内部定义,也可以在类内部声明,类外部定义友元函数。
friend void doingInfo1(Student& obj)
{
obj.pro_sno =1234;
obj.pri_phonenumber = 18192090902;
std::cout<<obj.pro_sno<<std::endl;
std::cout<<obj.pri_phonenumber<<std::endl;
}
friend void doingInfo2(Student& obj);
void doingInfo2(Student& obj)
{
obj.pri_address = "BeiJing";
obj.pro_sno=123;
std::cout<<obj.pri_address<<std::endl;
std::cout<<obj.pro_sno<<std::endl;
}
经验证代码正常运行,可验证友元函数可以访问protected与private成员。
(5)验证友元类
概念:
友元类是一个类,它可以访问另一个类的所有私有和保护成员。被声明为友元类的类相当于有权访问另一个类的私有实现细节。
特点:
- 友元类的所有成员函数(包括构造函数、析构函数等)都可以访问被授予友元权限的类的私有和保护成员。
- 通常用于需要两个类之间有非常紧密合作的场景。
声明友元类Person
class Person
{
};
并在Student类中做好定义
friend class Person;
之后便可以在友元类Person中访问Student中的所有成员!
值得注意的是:友元函数允许单个函数访问类的私有成员,而友元类允许整个类的所有成员函数访问另一个类的私有成员。这些机制适用于特殊的场景,如需要在两个类或函数之间紧密协作时使用,但应谨慎使用以避免破坏封装性和增加耦合度。
此处奉上源代码,供大家自行尝试:
#include <iostream>
#include <windows.h>
class Student
{
public:
std::string pub_name;
short pub_age;
std::string pub_gantal;
protected:
long pro_sno;
private:
long pri_phonenumber;
std::string pri_address;
public:
void initPubInfo(std::string pub_name,short pub_age,std::string pub_gantal)
{
this->pub_name = pub_name;
this->pub_age = pub_age;
this->pub_gantal = pub_gantal;
}
void showPubInfo()
{
std::cout<<"name: "<<this->pub_name<<","
<<"age: "<<this->pub_age<<","
<<"gental: "<<this->pub_gantal<<std::endl;
}
void initProInfo(long pro_sno)
{
this->pro_sno = pro_sno;
}
void showProInfo()
{
std::cout<<"student's sno: "<<this->pro_sno<<std::endl;
}
void initPriInfo(long pri_phonenumber,std::string pri_address)
{
this->pri_phonenumber = pri_phonenumber;
this->pri_address = pri_address;
}
void showPriInfo()
{
std::cout<<"phone number: "<<this->pri_phonenumber<<","
<<"address: "<<this->pri_address<<std::endl;
}
friend void doingInfo1(Student& obj)
{
obj.pro_sno =1234;
obj.pri_phonenumber = 18192090902;
std::cout<<obj.pro_sno<<std::endl;
std::cout<<obj.pri_phonenumber<<std::endl;
}
friend void doingInfo2(Student& obj);
friend class Person;
};
void doingInfo2(Student& obj)
{
obj.pri_address = "BeiJing";
obj.pro_sno=123;
std::cout<<obj.pri_address<<std::endl;
std::cout<<obj.pro_sno<<std::endl;
}
class Person
{
public:
void showStudent(Student& obj)
{
}
};
int main()
{
#ifdef _WIN32
// 设置控制台的编码为 UTF-8
SetConsoleOutputCP(CP_UTF8);
#endif
Student* student= new Student();
return 0;
}