《C++游戏编程入门》第9章 高级类与动态内存:Game Lobby

《C++游戏编程入门》第9章 高级类与动态内存:Game Lobby

    • 9.1 使用聚合体
        • 09.critter_farm.cpp
    • 9.2 使用友元函数与运算符重载
        • 09.friend_critter.cpp
    • 9.3 动态分配内存
        • 09.heap.cpp
    • 9.4 使用数据成员与堆
        • 09.heap_data_member.cpp
    • 9.5 Game Lobby程序
        • 09.game_lobby.cpp

9.1 使用聚合体

对象的组合,对象成员变量含其他对象。

09.critter_farm.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;class Critter
{
public:Critter(const string &name = "");string GetName() const;private:string m_Name; // 对象包含关系
};Critter::Critter(const string &name): m_Name(name)
{
}inline string Critter::GetName() const
{return m_Name;
}class Farm
{
public:Farm(int spaces = 1);void Add(const Critter &aCritter);void RollCall() const;private:vector<Critter> m_Critters;
};Farm::Farm(int spaces)
{m_Critters.reserve(spaces);
}void Farm::Add(const Critter &aCritter)
{m_Critters.push_back(aCritter);
}void Farm::RollCall() const
{for (vector<Critter>::const_iterator iter = m_Critters.begin(); iter != m_Critters.end(); ++iter)cout << iter->GetName() << " here.\n";
}int main()
{Critter crit("Poochie");cout << "My critter's name is " << crit.GetName() << endl;cout << "\nCreating critter farm.\n";Farm myFarm(3);cout << "\nAdding three critters to the farm.\n";myFarm.Add(Critter("Moe"));myFarm.Add(Critter("Larry"));myFarm.Add(Critter("Curly"));cout << "\nCalling Roll...\n";myFarm.RollCall();return 0;
}

9.2 使用友元函数与运算符重载

友元函数对类的任何成员都有完全的访问权。

09.friend_critter.cpp
#include <iostream>
#include <string>
using namespace std;class Critter
{// 友元函数friend void Peek(const Critter &aCritter);friend ostream &operator<<(ostream &os, const Critter &aCritter);public:Critter(const string &name = "");private:string m_Name;
};Critter::Critter(const string &name): m_Name(name)
{
}void Peek(const Critter &aCritter);
ostream &operator<<(ostream &os, const Critter &aCritter);int main()
{Critter crit("Poochie");cout << "Calling Peek() to access crit's private data member, m_Name: \n";Peek(crit);cout << "\nSending crit object to cout with the << operator:\n";cout << crit;return 0;
}void Peek(const Critter &aCritter)
{cout << aCritter.m_Name << endl;
}// 运算符重载
ostream &operator<<(ostream &os, const Critter &aCritter)
{os << "Critter Object - m_Name: " << aCritter.m_Name;return os;
}

9.3 动态分配内存

堆(自由存储区),程序员负责分配与释放。

09.heap.cpp
#include <iostream>
using namespace std;int *intOnHeap(); // returns an int on the heap
void leak1();     // creates a memory leak
void leak2();     // creates another memory leakint main()
{int *pHeap = new int;//new运算符*pHeap = 10;cout << "*pHeap: " << *pHeap << "\n\n";int *pHeap2 = intOnHeap();cout << "*pHeap2: " << *pHeap2 << "\n\n";cout << "Freeing memory pointed to by pHeap.\n\n";delete pHeap;//显示地释放cout << "Freeing memory pointed to by pHeap2.\n\n";delete pHeap2;// get rid of dangling pointerspHeap = nullptr;pHeap2 = 0;return 0;
}int *intOnHeap()
{int *pTemp = new int(20);//分配同时初始化return pTemp;
}void leak1()
{int *drip1 = new int(30);
}void leak2()
{int *drip2 = new int(50);drip2 = new int(100);delete drip2;
}

9.4 使用数据成员与堆

09.heap_data_member.cpp
#include <iostream>
#include <string>
using namespace std;class Critter
{
public:Critter(const string &name = "", int age = 0); // 构造函数~Critter();                                    // 析构函数Critter(const Critter &c);                     // 拷贝构造函数Critter &operator=(const Critter &c);          // 拷贝赋值运算符void Greet() const;private:string *m_pName;int m_Age;
};Critter::Critter(const string &name, int age)
{cout << "Constructor called\n";m_pName = new string(name); // 分配堆空间m_Age = age;
}Critter::~Critter() // destructor definition
{cout << "Destructor called\n";delete m_pName; // 释放堆空间
}Critter::Critter(const Critter &c) // copy constructor definition
{cout << "Copy Constructor called\n";m_pName = new string(*(c.m_pName));m_Age = c.m_Age;
}Critter &Critter::operator=(const Critter &c) // overloaded assignment op def
{cout << "Overloaded Assignment Operator called\n";if (this != &c){delete m_pName;m_pName = new string(*(c.m_pName));m_Age = c.m_Age;}return *this;
}void Critter::Greet() const
{cout << "I'm " << *m_pName << " and I'm " << m_Age << " years old. ";cout << "&m_pName: " << &m_pName << endl;
}void testDestructor();
void testCopyConstructor(Critter aCopy);
void testAssignmentOp();int main()
{testDestructor();cout << endl;Critter crit("Poochie", 5);crit.Greet();testCopyConstructor(crit);crit.Greet();cout << endl;testAssignmentOp();return 0;
}void testDestructor()
{Critter toDestroy("Rover", 3);toDestroy.Greet();
}void testCopyConstructor(Critter aCopy)
{aCopy.Greet();
}void testAssignmentOp()
{Critter crit1("crit1", 7);Critter crit2("crit2", 9);crit1 = crit2;crit1.Greet();crit2.Greet();cout << endl;Critter crit3("crit", 11);crit3 = crit3;crit3.Greet();
}

9.5 Game Lobby程序

09.game_lobby.cpp
#include <iostream>
#include <string>
using namespace std;class Player
{
public:Player(const string &name = "");string GetName() const;Player *GetNext() const;void SetNext(Player *next);private:string m_Name;Player *m_pNext; // Pointer to next player in list
};Player::Player(const string &name): m_Name(name), m_pNext(nullptr)
{
}string Player::GetName() const
{return m_Name;
}Player *Player::GetNext() const
{return m_pNext;
}void Player::SetNext(Player *next)
{m_pNext = next;
}class Lobby
{friend ostream &operator<<(ostream &os, const Lobby &aLobby);public:Lobby();~Lobby();void AddPlayer();void RemovePlayer();void Clear();private:Player *m_pHead;
};Lobby::Lobby(): m_pHead(nullptr)
{
}Lobby::~Lobby()
{Clear();
}void Lobby::AddPlayer()
{// create a new player nodecout << "Please enter the name of the new player: ";string name;cin >> name;Player *pNewPlayer = new Player(name);// if list is empty, make head of list this new playerif (m_pHead == nullptr){m_pHead = pNewPlayer;}// otherwise find the end of the list and add the player thereelse{Player *pIter = m_pHead;while (pIter->GetNext() != nullptr)pIter = pIter->GetNext();pIter->SetNext(pNewPlayer);}
}void Lobby::RemovePlayer()
{if (m_pHead == nullptr){cout << "The game lobby is empty.  No one to remove!\n";}else{Player *pTemp = m_pHead;m_pHead = m_pHead->GetNext();delete pTemp;}
}void Lobby::Clear()
{while (m_pHead != nullptr)RemovePlayer();
}ostream &operator<<(ostream &os, const Lobby &aLobby)
{Player *pIter = aLobby.m_pHead;os << "\nHere's who's in the game lobby:\n";if (pIter == nullptr){os << "The lobby is empty.\n";}else{while (pIter != nullptr){os << pIter->GetName() << endl;pIter = pIter->GetNext();}}return os;
}int main()
{Lobby myLobby;int choice;do{cout << myLobby;cout << "\nGAME LOBBY\n";cout << "0 - Exit the program.\n";cout << "1 - Add a player to the lobby.\n";cout << "2 - Remove a player from the lobby.\n";cout << "3 - Clear the lobby.\n\n";cout << "Enter choice: ";cin >> choice;switch (choice){case 0:cout << "Good-bye.\n";break;case 1:myLobby.AddPlayer();break;case 2:myLobby.RemovePlayer();break;case 3:myLobby.Clear();break;default:cout << "That was not a valid choice.\n";}} while (choice != 0);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/742780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

22.5 RabbitMQ

22.5 RabbitMQ 1. RabbitMQ1.1 概念上的组成1.2 使用消息队列的好处1.3 消息队列特性1.4 RabbitMQ特点1.5 RabbitMQ核心概念2. 安装Rabbitmq2.1 基于Linux安装3. RabbitMQ常用命令4. 后台管理4.1 开启Rabbitmq管理后台4.2 admin用户配置5. 实战案例5.1 依赖引入

《安富莱嵌入式周报》第334期:开源SEM扫描电子显微镜,自制编辑器并搭建嵌入式环境,免费产品设计审查服务,实用电子技术入门,USB资料汇总,UDS统一诊断

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1om411Z714/ 《安富莱嵌入式周报》第334期&#xff1a;开源SEM…

​【已解决】npm install​卡主不动的情况

使用 npm install 初始化前端项目时&#xff0c;会出现卡住不动的情况。原因是淘宝镜像源由原来的https://registry.npm.taobao.org 更换为下面这个&#xff1a; https://registry.npmmirror.com 直接在终端执行下面的指令即可&#xff1a; npm config set registry https://re…

ABCDE联合创始人和普通合伙人BMAN确认出席Hack .Summit() 2024

ABCDE联合创始人和普通合伙人BMAN确认出席Hack .Summit() 2024&#xff01; ABCDE联合创始人和普通合伙人BMAN确认出席由 Hack VC 主办&#xff0c;并由 AltLayer 和 Berachain 联合主办&#xff0c;与 SNZ 和数码港合作&#xff0c;由 Techub News 承办的Hack.Summit() 2024区…

【Paper Reading】6.RLHF-V 提出用RLHF的1.4k的数据微调显著降低MLLM的虚幻问题

分类 内容 论文题目 RLHF-V: Towards Trustworthy MLLMs via Behavior Alignment from Fine-grained Correctional Human Feedback 作者 作者团队&#xff1a;由来自清华大学和新加坡国立大学的研究者组成&#xff0c;包括Tianyu Yu, Yuan Yao, Haoye Zhang, Taiwen He, Y…

VB播放器(动态服务器获取歌词)-183-(代码+说明)

转载地址: http://www.3q2008.com/soft/search.asp?keyword183 VBASP vb动态从服务器读取歌词 VB asp交互 程序, 模式不一样, 与普通的MP3播放器不一样, 这个是可以实现歌词从服务器上查询功能的. 看好了在咨询 我可以給您演示 目  录 前  言 1 1 . 简述 2 1.1 开发…

前端框架发展史

前端开发自互联网诞生之初就开始了它的演变历程&#xff0c;从最早的静态页面到今天的高度动态和交互式的应用程序&#xff0c;前端框架在这个进程中起到了核心的作用。这些框架不仅极大地推进了网页技术的边界&#xff0c;还改善了开发者的工作流程和最终用户的体验。让我们深…

阿里云国际DDoS高防接入配置最佳实践

业务接入DDoS高防产品后&#xff0c;可以将攻击流量引流到DDoS高防&#xff0c;有效避免业务在遭受大流量DDoS攻击时出现服务不可用的情况&#xff0c;确保源站服务器的稳定可靠。本文九河云的接入配置和防护策略最佳实践&#xff0c;在各类场景中使用DDoS高防更好地保护您的业…

Linux系统下基于VSCode和Cmake进行C++开发

目录 简介一、GCC编译器1.1创建cpp文件1.2编译过程1.3g重要编译参数 二、GDB调试器三、IDE-VScode3.1 VSCode常用快捷键3.2 swap测试 四、CMake4.1CMake介绍4.2 CMake语法特性介绍4.3 CMake重要指令和常用变量4.4 CMake编译流程4.5CMake代码实践 五、使用VSCode进行完整项目开发…

【JavaScript】面试手撕柯里化函数

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 引入柯里化定义实现快速使用柯里化的作用提高自由度bind函数 参考资料 引入 上周…

开源绘图工具 PlantUML 入门教程(常用于画类图、用例图、时序图等)

文章目录 一、类图二、用例图三、时序图 一、类图 类的UML图示 startuml skinparam classAttributeIconSize 0 class Dummy {-field1 : String#field2 : int~method1() : Stringmethod2() : void } enduml定义能见度&#xff08;可访问性&#xff09; startumlclass Dummy {-f…

ES6(一):let和const、模板字符串、函数默认值、剩余参数、扩展运算符、箭头函数

一、let和const声明变量 1.let没有变量提升&#xff0c;把let放下面打印不出来&#xff0c;放上面可以 <script>console.log(a);let a1;</script> 2.let是一个块级作用域,花括号里面声明的变量外面找不到 <script>console.log(b);if(true){let b1;}//und…

C语言探索旅程之【柔性数组】

目录 1. 柔性数组的定义 2. 柔性数组的使用 3. 柔性数组的注意事项 4. 柔性数组的优点 5. 柔性数组的应用场景 当我们谈到C语言中的柔性数组时&#xff0c;我们指的是一种特殊的数组&#xff0c;其大小在运行时动态确定&#xff0c;而不是在编译时确定。柔性数组是C语言中…

分布式搜索引擎Elasticsearch中各种类型节点的作用

Elasticsearch 是一个分布式搜索和分析引擎&#xff0c;它可以在多个节点上运行&#xff0c;每个节点承担着集群中的不同角色和职责。以下是Elasticsearch中常见的几种节点类型以及它们的作用&#xff1a; 主节点&#xff08;Master Node&#xff09; 主要负责管理集群的全局…

vscode插件开发-发布插件

安装vsce vsce是“Visual Studio Code Extensions”的缩写&#xff0c;是一个用于打包、发布和管理VS Code扩展的命令行工具。 确保您安装了Node.js。然后运行&#xff1a; npm install -g vscode/vsce 您可以使用vsce轻松打包和发布扩展&#xff1a; // 打包插件生成name…

一.java介绍和idea基础使用

java技术体系 Java技术体系说明Java SE(Java standard Edition):标准版Java技术的核心和基础Java EE(Java Enterprise Edition):企业版企业级应用开发的一套解决方案Java ME(Java Micro Edition):小型版针对移动设备应用的解决方案&#xff08;认可少&#xff0c;主要是安卓和…

目标跟踪SORT算法原理浅析

SORT算法 Simple Online and Realtime Tracking(SORT)是一个非常简单、有效、实用的多目标跟踪算法。在SORT中&#xff0c;仅仅通过IOU来进行匹配虽然速度非常快&#xff0c;但是ID switch依然非常严重。 SORT最大特点是基于Faster RCNN的目标检测方法&#xff0c;并利用卡尔…

Unity开发中Partial 详细使用案例

文章目录 **1. 分割大型类****2. 与 Unity 自动生成代码协同工作****3. 团队协作****4. 共享通用逻辑****5. 自定义编辑器相关代码****6. 配合 Unity 的 ScriptableObjects 使用****7. 多人协作与版本控制系统友好** 在 Unity 开发中&#xff0c; partial 关键字是 C# 语言提供…

【音视频开发】:RTSP服务器协议内容

一、什么是RTSP协议 RTSP是一个实时传输流协议&#xff0c;是一个应用层的协议。通常说的RTSP包括RTSP协议、RTP协议、RTCP协议。 RTSP协议&#xff1a;负责服务器与客户端之间的请求与相应RTP协议 &#xff1a;负责服务器与客户端之间传输媒体数据RTCP协议&#xff1a;负责提…

python基础02

缩进&#xff0c;而不是大括号 for x in array:if x<pivot:less.append(x)else:greater.append(x)函数和对象方法的调用 调用函数时&#xff0c;向函数括号传递0或多个参数&#xff0c;通常会把返回值赋值给一个变量&#xff1a; resultf(x,y,z)is 和 is not 检查两个引用…