java友元类_友元实例:友元类及友元函数

java友元类_友元实例:友元类及友元函数学习了 c 这么久 一直没有对友元进行了解 据说友元不是特别好用 据说 不是我说的 因此直到今天才去了解 其实友元确实不是很常用 但友元功能确实很实用 它不但能够释放类中的非公有成员 同时还能保证了类的封装性 用户可以有选择为具体的类或函数赋予 通行证 还是比较灵活的 比如 某个类去访问另一个类的私有成成员 或者一个函数去访问某个类的私有成员等等 都可以使用友元来实现 下面就友元做了两个小例子

学习了c++这么久,一直没有对友元进行了解,据说友元不是特别好用(据说,不是我说的),因此直到今天才去了解。其实友元确实不是很常用,但友元功能确实很实用,它不但能够释放类中的非公有成员,同时还能保证了类的封装性。用户可以有选择为具体的类或函数赋予“通行证”。还是比较灵活的。比如:某个类去访问另一个类的私有成成员,或者一个函数去访问某个类的私有成员等等,都可以使用友元来实现。

下面就友元做了两个小例子,望高手指教。(每段代码都在不同的文件中)

首先是关于友元类的代码,就一句话,很简单。。。

Test.h:

#ifndef TEST_H

#define TEST_H

#include

using namespace std;

class Test

{

friend class FriendTest; //此处声明FriendTest为Test的友元类,FriendTest类可以访问Test的私有成员

public:

Test();

void set(int h,int w);

void print();

virtual ~Test();

protected:

private:

int height;

int weight;

};

#endif // TEST_H

Test.cpp

#include “../include/Test.h”

Test::Test()

{

//ctor

height = 0;

weight = 0;

}

void Test::set(int h, int w)

{

height = h;

weight = w;

}

void Test::print()

{

cout << height << " ";

cout << weight <

}

Test::~Test()

{

//dtor

}

下面关于FriendTest的相关程序。

FriendTest.h

#ifndef FRIENDTEST_H

#define FRIENDTEST_H

#include “Test.h”

class FriendTest

{

public:

FriendTest();

void setTest(Test& t, int h, int w);

virtual ~FriendTest();

protected:

private:

};

#endif // FRIENDTEST_H

FriendTest.cpp

#include “../include/FriendTest.h”

FriendTest::FriendTest()

{

//ctor

}

void FriendTest::setTest(Test& t, int h, int w) //之前声明了友元,所以此处可以调用私有成员

{

t.height = h;

t.weight = w;

}

FriendTest::~FriendTest()

{

//dtor

}#include

#include “./include/Test.h”

#include “./include/FriendTest.h”

using namespace std;

int main()

{

Test t;

FriendTest ft;

t.set(30, 20);

ft.setTest(t,9,8);

t.print();

return 0;

}

接下来是关于友元函数的问题,友元函数我弄了很久,对于某个类来说,只希望其某个函数为友元,需要对函数进行友元声明。然而将上边代码中的友元类的声明改成友元函数的声明,编译不通过,提示未定义。后来发现对于友元函数来说两个类必须放在同一个文件中,并且要有部分调整,具体实现如下,并富有详解。

部分代码省略。。。主要代码如下:

#include

using namespace std;

//由于两个类都使用到了另一个类,所以顺序很关键。如果将两个类的顺序颠倒会出现编译不通过,并提示未定义。另外友元函数必须在最后实现,因为它用到了两个类中的成员。仔细与上一部分的代码比较,你便会了解里边的玄机。。。

class Test; //首先需要声明Test类,FriendTest类中需要使用。

class FriendTest

{

public:

FriendTest();

void setTest(Test& t, int h, int w);

virtual ~FriendTest();

protected:

private:

};

class Test

{

friend void FriendTest::setTest(Test& t, int h, int w); //友元函数声明

public:

Test();

void set(int h,int w);

void print();

virtual ~Test();

protected:

private:

int height;

int weight;

};

void FriendTest::setTest(Test& t, int h, int w)

{

t.height = h;

t.weight = w;

}

int main()

{

cout << "friend" <

Test t;

FriendTest ft;

t.set(30, 20);

ft.setTest(t,9,8);

t.print();

return 0;

}

另外在网上看到了一个关于primer c++中一个友元例子的讲解可能对你理解有些帮助:

做了部分修改。。。。。。

第一种写法问题:

编译到Screen时,由于Screen类使用到Window_Mgr的成员函数,前面给出了Window_Mgr的声明,但不清楚Window_Mgr的完整定义,对成员函数不清楚,所以友元函数声明不成立,编译出错。

class Window_Mgr

class Screen

{

public:

friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s);

private:

int height;

int width;

}

class Window_Mgr

{

public:

typedef std::string::size_type index;

Window_Mgr& Window_Mgr::relocate(index r, index c, Screen& s)

{

s.height += r;

s.width += c;

return *this;

}

}

第二种写法问题在于:

编译到relocate时,由于Screen& s的实现使用到Screen的成员变量,虽然前面给出了Screen的声明,但此时还不清楚Screen的完整定义,所以编译出错。

class Screen;

class Window_Mgr

{

public:

typedef std::string::size_type index;

Window_Mgr& Window_Mgr::relocate(index r, index c, Screen& s)

{

s.height += r;

s.width += c;

return *this;

}

}

class Screen

{

public:

friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s);

private:

int height;

int width;

}

第三种写法:

将Window_Mgr::relocate的实现移动到最后,由于编译类Window_Mgr时,并不需要Screen&s 的实现细节,问题得到解决

class Screen;

class Window_Mgr

{

public:

typedef std::string::size_type index;

Window_Mgr& Window_Mgr::relocate(index r, index c, Screen& s);   //无内部成员的使用

}

class Screen

{

public:

friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s);

private:

int height;

int width;

}

Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s)

{

s.height += r;

s.width += c;

return *this;

}

可见,这两个类如果编译成功需要严格的交替顺序

这也就解释了为什么放在两个文件中无法编译。

附录:

一开始的实现的不能编译的两个文件

实现分别如下:Window_Mgr.h

#ifndef WINDOW_MGR //为了避免两个文件嵌套

#define WINDOW_MGR

#include

#include

class Window_Mgr

{

public:

typedef std::string::size_type index;

Window_Mgr& Window_Mgr::relocate(index r, index c, Screen& s)

{

s.height += r;

s.width += c;

return *this;

}

}

#endif

Screen.h

#ifndef SCREEN

#define SCREEN

#include “Window_Mgr.h”

class Screen

{

public:

friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r, Window_Mgr::index c, Screen& s);

private:

int height;

int width;

}

#endif

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220572.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午8:10
下一篇 2026年3月17日 下午8:10


相关推荐

  • unity3d 激活成功教程

    unity3d 激活成功教程用 Unity exe 覆盖安装目录下的同名文件 nbsp 运行 Unity 选择 Manualacivat 然后加载 UnityLicence ilf 文件 nbsp 下载地址 u 115 com file f5f99375c3 nbsp 或则 CSDN http download csdn net source nbsp nbsp

    2026年3月20日
    2
  • flocked翻译_physicked翻译

    flocked翻译_physicked翻译FleckisaWebSocketserverimplementationinC#.BranchedfromtheNuggetproject,Fleckrequiresnoinheritance,container,oradditionalreferences.ExampleThefollowingisanexamplethatwillecho…

    2025年6月21日
    6
  • 调制解调器(Modem)

    调制解调器(Modem)调制解调器调制解调器 英语 Modem modulator demodulator 的英文缩写 是一个将数字信号调变到模拟信号上进行传输 并解调收到的模拟信号以得到数字信号的电子设备 它的目标是产生能够方便传输的模拟信号并且能够通过解码还原原来的数字信号 根据不同的应用场合 调制解调器可以使用不同的手段来传送模拟信号 比如使用光纤 射频无线电或电话线等 使用普通电话线音频波

    2026年3月18日
    2
  • 使用 WinSCP(下载) 上文件到 Linux图文教程

    使用 WinSCP(下载) 上文件到 Linux图文教程问题导读:1.如何远程链接?2.如何上传文件?3.如何对立面的文件进行操作?4.什么情况下会链接失败?https://yunpan.cn/cYWtNMycjeVPv 访问密码4f

    2022年8月4日
    20
  • 【知识普及】平板的屏幕分辨率和屏幕比例_和平精英平板分辨率

    【知识普及】平板的屏幕分辨率和屏幕比例_和平精英平板分辨率针对IOS,Android手机分辨率大小、屏幕尺寸、开发尺寸的参考。在实际页面的开发过程,往往显示屏幕的宽度换算为像素尺寸的1/2。IOS:6.5英寸——1242x2688px——XsMax6.1英寸——828x1792px——XR5.8英寸——1125x2436px——X/Xs5.5英寸——1242x2208px——6+…

    2022年8月13日
    5
  • ES6 类的使用(class)

    ES6 类的使用(class)

    2022年4月3日
    48

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号