• Index

前置声明和友元声明

Reads: 31

前置声明

基础示例

#include <iostream>

// 前置声明
class B;

class A
{
private:
    B *b;
};

class B
{
private:
    A *a;
};

int main(void)
{
    return 0;
}

基础讲解

类A和类B相互使用对方的指针,由于类B在类A后面,如果没有前置声明的话,那么编译的时候,编译器就会报错,说类A中的类型B没有定义。代码中的class B;就是类B的前置声明。

友元声明

我们知道每一个类,多多少少都会有私有或者保护的成员。有时候会有这种情况,需要声明定义一个非类成员的函数,然后这个函数还要访问类的私有或者保护的成员。这时候需要使用关键字friend

基础示例 1

现在举个简单的例子说明非类成员的函数怎样访问类的私有或者保护的成员:

#include <iostream>
#include <string>

class testclass
{
private:
    friend void set_text(testclass &test, const std::u32string &text); // 声明一
    std::u32string m_value;
};

void set_text(testclass &test, const std::u32string &text); // 声明二
void error_set_text(testclass &test, const std::u32string &text); // 声明三

int main(void)
{
    testclass test;
    set_text(test, U"小古银的C++教程");
    return 0;
}

void set_text(testclass &test, const std::u32string &text)
{
    test.m_value = text;
}

void error_set_text(testclass &test, const std::u32string &text)
{
    // 去掉下面注释编译将会错误
    // test.m_value = text;
}

基础讲解 1

只需要将函数set_text()的声明放在类里面(无论是放在哪个访问限制都可以),并且在声明的开头加上friend,那么这个函数就算不是成员函数,但也能通过对象访问对象的私有或者保护成员。例如代码中的函数set_text()里面可以通过对象test操作其私有的成员变量m_value。而friend只能够加在函数声明的前面,而不能够加在函数定义的前面。

虽然函数set_text()的声明放在类里面,但是它的确已经声明了,所以代码中的声明二可以省略。

而函数error_set_text()没有在类里面声明为friend,所以如果去掉函数error_set_text()里的代码注释,将会编译报错,提示不能访问私有成员。

基础示例 2

#include <string>

class testclass
{
private:
    // 它虽然在类里面声明和定义, 但它不是成员函数
    friend void set_text(testclass &test, const std::u32string &text)
    {
        test.m_value = text;
    }
    std::u32string m_value;
};

int main(void)
{
    testclass test;
    set_text(test, U"小古银的C++教程");
    return 0;
}

基础讲解 2

上面代码是把函数set_text()的声明和定义都放在类里面,但是函数set_text()仍然是全局函数。

基础示例 3

class A
{
private:
    // 将类B的前置声明写到类A中并且在开头加上friend
    friend class B;
    using int_type = int;
};

class B
{
private:
    A::int_type value;
};

int main(void)
{
    return 0;
}

基础讲解 3

把类B的前置声明写到类A里面,并且在前置声明前面加上friend说明类B是类A的友元类,这样类B就可以访问类A中的私有或者保护的成员。上面代码中类B可以访问类A的成员类型int_type,并且有这个类型声明了私有成员变量value


Comments

Make a comment

  • Index

WARNING: You are using an old browser that does not support HTML5. Please choose a modern browser (Chrome / Microsoft Edge / Firefox / Sarafi) to get a good experience.