友元成员函数使用时的注意事项

友元成员函数的注意事项

友元的概念

“友元”的概念其实是针对于类的私有成员来说的,一个类的由于封装的缘故,类体中私有成员是不可以被外界访问的,无论是继承也好,都是无法访问类内私有成员的。但是正是有那么一些人,愿意打破陈规破例访问类体内的私有成员,此时“友元”的概念闪亮登场。其实我们的普通函数是可以访问类体中的public,但是自从来了“友元”,protected和private类型的变量都被尽收眼底,无处可藏。

友元成员函数中的注意事项

友元成员函数声明和定义的顺序必须满足一定要求,否则VS2017会报错。

#include <iostream>  
#include <string>  
using namespace std;  
  
class Person;  
class Student  
{  
public:  
    void ShowInf(Person& PersonObject);  
};  
  
class Person  
{  
    friend void Student::ShowInf(Person& PersonObject);  
private:  
    int age;  
    string name;  
public:  
    Person(string name, int age)  
    {  
        this->name = name;  
        this->age = age;  
    }  
    Person(Person& PersonObject)  
    {  
        this->name = PersonObject.name;  
        this->age = PersonObject.age;  
    }  
    Person operator = (Person PersonObject)  
    {  
        this->age = PersonObject.age;  
        this->name = PersonObject.name;  
    }  
};  
  
void Student::ShowInf(Person& PersonObject)  
{  
    cout << PersonObject.name << "的年龄为" << PersonObject.age << endl;  
}  
  
int main()  
{  
    Person PersonObject("张三", 19);  
    Student StudentObject;  
    StudentObject.ShowInf(PersonObject);  
}  

我们这里用Student类中的ShowInf()成员函数访问Person类中的私有成员name和age。

① 首先,我们先声明可以下Person类类型,这样我们才可以在下面定义Student类使用这个数据类型,但是一定要注意,此时的Person类是个空类只是个声明我任何实际成员参数,因此我们Student中的ShowInf()要在Person类定义完后在进行定义,此时我们才可以在Student中的ShowInf()中访问Person类中的成员,这里我们先给Student中的ShowInf()函数一个类内声明;

② 定义Person类的实体,在定义Person类实体之前,千万不要定义Student中的ShowInf()函数,因为Person类实体未定义之前我们也不知道Person类中有什么成员;

③ 定义Student类中可以访问呢Person类私有成员的函数实体,此时定义实体才有意义,编译器才不会报错,因为,这个时候Person类内有啥已经知道了,访问Person类中的成员也就顺理成章了。

④ 特别注意:这里我们只能通过向函数传递形参来访问Person类中的私有成员,因为在Person实体未定义之前,编译器是不允许我们定义Person类的对象的。

错误示例

#include <iostream>  
#include <string>  
using namespace std;  
  
class Person;  
class Student  
{  
private:  
        Person PersonObject;  
public:  
    void ShowInf();  
        Student(Person PersonObject)  
        {  
            this->PersonObject = PersonObject;  
        }  
};  
  
class Person  
{  
    friend void Student::ShowInf();  
private:  
    int age;  
    string name;  
public:  
    Person(string name, int age)  
    {  
        this->name = name;  
        this->age = age;  
    }  
    Person(Person& PersonObject)  
    {  
        this->name = PersonObject.name;  
        this->age = PersonObject.age;  
    }  
    Person operator = (Person PersonObject)  
    {  
        this->age = PersonObject.age;  
        this->name = PersonObject.name;  
    }  
};  
  
void Student::ShowInf()  
{  
    cout << PersonObject.name << "的年龄为" << PersonObject.age << endl;  
}  
  
int main()  
{  
    Person PersonObject("张三", 19);  
    Student StudentObject(PersonObject);  
    StudentObject.ShowInf();  
}  

这里,我们在未定义Person实体之前(仅仅定义了一个Person类的声明)就在Student类体内定义Person类的成员函数,这样的话编译器并不知道给Person类对象分配多少内存空间,因此此时编译器会报错!

我们一定要注意:在未定义的类实体之前,一定不要贸然的在其他类体内定义该类类型的对象作为成员变量。

猜你喜欢

转载自blog.csdn.net/weixin_45590473/article/details/109303308