c++ primer,友元函数上的一个例子(By Sybase)
本文试图解释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)的更多相关文章
- SpringBoot应用和PostgreSQL数据库部署到Kubernetes上的一个例子
创建一个名为ads-app-service的服务: 上述Service的yaml文件里每个字段,在Kubernetes的API文档里有详细说明. https://kubernetes.io/docs/ ...
- 读书笔记 effective c++ Item 23 宁可使用非成员非友元函数函数也不使用成员函数
1. 非成员非友元好还是成员函数好? 想象一个表示web浏览器的类.这样一个类提供了清除下载缓存,清除URL访问历史,从系统中移除所有cookies等接口: class WebBrowser { pu ...
- C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...
- 关于C++中的friend友元函数的总结
1.友元函数的简单介绍 1.1为什么要使用友元函数 在实现类之间数据共享时,减少系统开销,提高效率.如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数. ...
- matlab实现梯度下降法(Gradient Descent)的一个例子
在此记录使用matlab作梯度下降法(GD)求函数极值的一个例子: 问题设定: 1. 我们有一个$n$个数据点,每个数据点是一个$d$维的向量,向量组成一个data矩阵$\mathbf{X}\in \ ...
- C++语言债券系列之十一——友元函数和拷贝构造函数
1.好友功能 (1)友元函数类的普通功能外定义. 定义友元函数和相同的正常功能.在类必须声明的正常功能为好友. (2)友元函数不是一个成员函数. 你不能反对打电话.但直接调用:友元函数访问类的公共.p ...
- 【C++基础 05】友元函数和友元类
友元是一种定义在类外部的普通函数或类,但它须要在类体内进行说明,为了与该类的成员函数加以差别,在说明时前面加以keywordfriend. 友元不是成员函数,可是它能够訪问类中的私有成员. 友元的作用 ...
- [C/C++] 友元函数和友元类
A---友元函数: class Data{ public: ... friend int f(int &m);//友元函数 ... } 友元函数是可以直接访问类的私有成员的非成员函数.它是定义 ...
- 一个例子让你秒懂 Qt Creator 编译原理
小北师兄作品 首发于微信公众号 小北师兄 微信 ID: ncuneupa 由于排版原因,文章可能读起来不太清晰,如果想看更好的排版,可以来我的公众号:小北师兄 大家好,我是你们的小北师兄,由于工作原因 ...
随机推荐
- 【兼容】IE下PNG色差
IE(包括IE7)中的PNG色差问题http://bbs.blueidea.com/thread-2910513-1-1.html修正IE对PNG颜色显示错误的问题http://www.lizhenw ...
- windows2003远程桌面退出后系统自动注销的解决方法
最近公司有一个奇怪的需求,意思是有一个网页,要时时的打开着.现在只有把这个网页在服务器上打开. 这样才能满足需求.但我在应用中遇见了个问题.我在服务器上打开网页后,关掉远程,过一会网页的运行效果就没有 ...
- 多线程程序设计学习(6)Producer-Consumer模式
Producer-Consumer[生产消费者模式]一:Producer-Consumer pattern的参与者--->产品(蛋糕)--->通道(传递蛋糕的桌子)--->生产者线程 ...
- (转载)【C++】new A和new A()的区别详解
(转载)http://blog.csdn.net/xiajun07061225/article/details/8796257 我们在C++程序中经常看到两种new的使用方式:new A以及new A ...
- HDU 5637 Transform 搜索
题意:bc round 74 div1 1002 中文题 分析(官方题解):注意到答案实际上只和s⊕t有关, bfs预处理下从0到xx的最短步数, 然后查询O(1)回答即可. #include < ...
- 解决:Eclipse导入工程后全是错误,连基本类型都不识别
当初在大学没时间完成作业时,总是喜欢网上搜一个或者拷贝同学的一个工程过来,导入到Eclipse中却全是红叉,连基本类型都不识别. 当时就纳闷了,难道是天要亡我之心不死?后来慢慢了解了,其实是导入的工程 ...
- php框架Symfony资料
1.http://snippets.symfony-project.org/snippets/tagged/criteria/order_by/date 2.Propel API: http://ap ...
- grails2.3.11第一课
以指令的方式Getting Started 1. 创建一个项目 grails create-app HelloGrails 2. 因为我环境变量中配置的jdk是1.8的,所以我要把这个项目搞到IDEA ...
- MyEclipse整合Git
1. 在OSC@China申请账号,建立项目 2. MyEclipse中选择导入项目-->Git-->Projects from Git 3. 填入Git的地址.User Name和Pas ...
- Spark环境的搭建与运行
Spark本地安装与配置 下载spark后解压,并cd到解压目录下 运行实例程序测试是否一切正常 ./bin/run-example org.apache.spark.examples.SparkPi ...