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 由于排版原因,文章可能读起来不太清晰,如果想看更好的排版,可以来我的公众号:小北师兄 大家好,我是你们的小北师兄,由于工作原因 ...
随机推荐
- MVC 5 的 EF6 Code First 入门
英文渣水平,大伙凑合着看吧…… 这是微软官方SignalR 2.0教程Getting Started with Entity Framework 6 Code First using MVC 5 系列 ...
- (转载)linux环境变量
转自:http://www.cnblogs.com/growup/archive/2011/07/02/2096142.html Linux 的变量可分为两类:环境变量和本地变量 环境变量,或者称为全 ...
- PICT实现组合测试用例(二)
上次简单总结了PICT命令的一些用法,这次重新把<软件测试实战>里面有关这一章的内容再总结一次,以巩固理解. 组合测试的概念 组合测试(combinatorial testing)是一种测 ...
- 【译】 AWK教程指南 附录C-AWK的内建函数
C.1 字串函数 index( 原字串, 查找的子字串 ) 若原字串中含有欲寻找的子字串,则返回该子字串在原字串中第一次出现的位置,若未曾出现该子字串则返回0. 例如: $ awk 'BEGIN{ p ...
- android NDK 实用学习(三)- java端类对象的构造及使用
1,读此文章前我假设你已经读过: android NDK 实用学习-获取java端类及其类变量 android NDK 实用学习-java端对象成员赋值和获取对象成员值 2,java端类对象的构造: ...
- Linux PHP实现仿百度文库预览功能
1.安装openoffice: tar zxvf OOo_3.3.0_Linux_x86-64_install-rpm-wJRE_zh-CN.tar.gzcd RPEMrpm -ivh *.rpm安装 ...
- 解决OpenCV Error:Insufficient memory(Failed to allocate 1244164 bytes) in unknown function
从师兄那拷贝过来的代码,师兄的机器上可以运行,环境为Win7+OpenCV231,编译器为Debug Win32,拷贝到自己机器上运行时出现问题. 本机的运行环境为win10+OpenCV244,编译 ...
- leetcode@ [208] Implement Trie (Prefix Tree)
Trie 树模板 https://leetcode.com/problems/implement-trie-prefix-tree/ class TrieNode { public: char var ...
- Turn Your Raspberry Pi Into a WiFi Hotspot with Edimax Nano USB EW-7811Un (RTL8188CUS chipset)
http://www.daveconroy.com/turn-your-raspberry-pi-into-a-wifi-hotspot-with-edimax-nano-usb-ew-7811un- ...
- JSP学习笔记2
<JAVA遇见HTML——JSP篇>学习笔记(下) 1.Javabean Javabeans就是符合某种规范的java类,使用Javabeans的好处是[解决代码的重复编写],减少代码冗余 ...