本文试图解释c++ primer Screen 和 Window_Mgr的例子,为什么将两个类放在两个文件中无法编译?

将两个类写在同一个文件中,通过三个例子解释问题:

第一种写法问题:

编译到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 <string>

#include <Screen.h>

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

c++ primer,友元函数上的一个例子(By Sybase)的更多相关文章

  1. SpringBoot应用和PostgreSQL数据库部署到Kubernetes上的一个例子

    创建一个名为ads-app-service的服务: 上述Service的yaml文件里每个字段,在Kubernetes的API文档里有详细说明. https://kubernetes.io/docs/ ...

  2. 读书笔记 effective c++ Item 23 宁可使用非成员非友元函数函数也不使用成员函数

    1. 非成员非友元好还是成员函数好? 想象一个表示web浏览器的类.这样一个类提供了清除下载缓存,清除URL访问历史,从系统中移除所有cookies等接口: class WebBrowser { pu ...

  3. C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...

  4. 关于C++中的friend友元函数的总结

    1.友元函数的简单介绍 1.1为什么要使用友元函数 在实现类之间数据共享时,减少系统开销,提高效率.如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数. ...

  5. matlab实现梯度下降法(Gradient Descent)的一个例子

    在此记录使用matlab作梯度下降法(GD)求函数极值的一个例子: 问题设定: 1. 我们有一个$n$个数据点,每个数据点是一个$d$维的向量,向量组成一个data矩阵$\mathbf{X}\in \ ...

  6. C++语言债券系列之十一——友元函数和拷贝构造函数

    1.好友功能 (1)友元函数类的普通功能外定义. 定义友元函数和相同的正常功能.在类必须声明的正常功能为好友. (2)友元函数不是一个成员函数. 你不能反对打电话.但直接调用:友元函数访问类的公共.p ...

  7. 【C++基础 05】友元函数和友元类

    友元是一种定义在类外部的普通函数或类,但它须要在类体内进行说明,为了与该类的成员函数加以差别,在说明时前面加以keywordfriend. 友元不是成员函数,可是它能够訪问类中的私有成员. 友元的作用 ...

  8. [C/C++] 友元函数和友元类

    A---友元函数: class Data{ public: ... friend int f(int &m);//友元函数 ... } 友元函数是可以直接访问类的私有成员的非成员函数.它是定义 ...

  9. 一个例子让你秒懂 Qt Creator 编译原理

    小北师兄作品 首发于微信公众号 小北师兄 微信 ID: ncuneupa 由于排版原因,文章可能读起来不太清晰,如果想看更好的排版,可以来我的公众号:小北师兄 大家好,我是你们的小北师兄,由于工作原因 ...

随机推荐

  1. boostrap兼容ie及其案例

    多梦网络 wordpress主题 http://www.dmeng.net/

  2. 怎么找到MyEclipse->add struts capabilities

    问:MyEclipse:我的工程右键可以MyEclipse->add struts capabilities之前有,后来不知怎么就没有了,谁知道怎么弄出来是struts 答:你已经add过一次了 ...

  3. Hibernate之HQL介绍

    Hibernate中提供了多种检索对象的方式,主要包括以下种类: 导航对象图检索方式:根据已经加载的对象导航到其他对象 OID检索方式:根据对象的OID来检索对象 HQL检索方式:使用面向对象的HQL ...

  4. 初识NuGet - 概念, 安装和使用

    1. NuGet是什么? NuGet is a Visual Studio 2010 extension that makes it easy to add, remove, and update l ...

  5. 使用CSS3美化复选框checkbox

    我们知道HTML默认的复选框样式十分简陋,而以图片代替复选框的美化方式会给页面表单的处理带来麻烦,那么本文将结合实例带您一起了解一下使用CSS3将复选框checkbox进行样式美化,并且带上超酷的滑动 ...

  6. Google Maps API v2 Demo Tutorial

    申请API KEY https://code.google.com/apis/console/?noredirect 1. 创建项目,名称随意,只是为了区分 2. 开启Google Maps Andr ...

  7. [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.5.5

    Show that the inner product $$\bex \sef{x_1\vee \cdots \vee x_k,y_1\vee \cdots\vee y_k} \eex$$ is eq ...

  8. selenium Grid

    Selenium Grid 的机制是启动一个 hub,然后启动多个 Selenium RC 注册到 hub 上, 当测试请求到 hub 时,hub 会将测试分发给 Selenium RC, Selen ...

  9. HDU-4696 Answers 纯YY

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4696 题意:给一个图,每个点的出度为1,每个点的权值为1或者2.给n个询问,问是否能找到一条路径的权值 ...

  10. HDU-4691 Front compression 后缀数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691 后缀数组模板题,求出Height数组后,对Height做RMQ,然后直接统计就可以了... // ...