热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C++类指针和所有权

如何解决《C++类指针和所有权》经验,为你挑选了1个好方法。

因此,我在C ++中重新创建了Pong(将ncurses用于终端hijinks,因为尝试仅通过控制台来完成它比我想象的要难得多)。这已经有一段时间了,它的意思是“刷新C ++”,我想使用Unity进行一些Hobby游戏开发。

我想:“至少我应该先用C ++制作一个简单的游戏,以证明我什至可以从Unity开始。” Pong是您需要处理的明显选择:对象,游戏状态,碰撞,运动矢量。

在刷新C ++的过程中,我不得不查找许多新事物,并提醒自己一些被遗忘的事情(自接触C ++已有10年了)。我不太清楚的一件事是关于类的指针的详细信息。(顺便说一下,这里有一个非常基本的版本,包括球和桨/碰撞):https : //pastebin.com/5NHjEjxX到目前为止,我只花了几个小时。

具体来说,我在这里记不清一件事:

const int boardWidth = 60;
const int boardHeight = 12;
Ball ball = Ball(-1,1,(boardWidth/2),(boardHeight/2));
Ball *p_ball = &ball;
Paddle paddle1 = {4,(boardHeight/2),3};
Paddle *p_paddle1 = &paddle1;
Paddle paddle2 = {(boardWidth-4), (boardHeight/2),3};
Paddle *p_paddle2 = &paddle2;
Board board; 

(这是在Game类初始化中。尽管我有点想知道是否应该将其放入构造函数中)。但是...。特别是当我声明Ball ball = Ball(-1,1,(boardWidth/2),(boardHeight/2));Paddle paddle1 = {4,(boardHeight/2),3};这些项“坐在”内存中在哪里?我承担堆?另外,我将如何以正确的方式删除这些内容(例如,球超出范围,我需要创建一个新球?)

我知道关于所有权的一些事情……我觉得这是使用&的错误方式,因为例如p_ball实际上不会“拥有”该类,而只是能够正确引用它?(我认为有一个术语“智能指针”,但是上次我接触C ++时还没有真正出现过)。如果有更合适的方法,我想知道!

我还被告知,无论如何都要避免在这些函数中通过引用传递引用,以避免使用指针并避免一起创建指针。



1> Miles Budnek..:

所有这些都是自动变量。当您达到当前范围的末尾时,它们的生命周期将结束。无需删除它们;一旦您达到当前范围的末尾,该操作就会自动发生。


如果您希望您的Game类对象拥有球,桨和板,则它们具有成员作用域是有意义的。即

class Game {
public:
    static const int BOARD_WIDTH = 60;
    static const int BOARD_HEIGHT = 12;

    Game()
        : ball{-1, 1, BOARD_WIDTH / 2, BOARD_HEIGHT / 2},
          paddle1{4, BOARD_HEIGHT / 2, 3},
          paddle2{BOARD_WIDTH - 4, BOARD_HEIGHT / 2, 3}
    {}

private:
    Ball ball;
    Paddle paddle1;
    Paddle paddle2;
    Board board;
};

这些成员对象将共享对象的生存期Game


指针只是指向其他对象的对象。它们不会影响它们指向的对象的寿命。例如,您可以从方法返回指向对象成员的指针。只要注意您的指针不会超出它们所指向的对象。

如果要使Game类包含指向其他对象的指针,则需要自己管理这些其他对象的生存期。例如,您可以动态分配它们。与直接将对象包含在对象中相比,这几乎没有什么优势Game,并且增加了大量的复杂性和开销。

在这里,我std::unique_ptr用于执行内存管理:

class Game {
public:
    static const int BOARD_WIDTH = 60;
    static const int BOARD_HEIGHT = 12;

    Game()
        : ball{std::make_unique(-1, 1, BOARD_WIDTH / 2, BOARD_HEIGHT / 2)},
          paddle1{std::make_unique(4, BOARD_HEIGHT / 2, 3)},
          paddle2{std::make_unique(BOARD_WIDTH - 4, BOARD_HEIGHT / 2, 3)},
          board{std::make_unique()}
    {}

    // Copying is implicitly disallowed since std::unique_ptr is non-copyable.
    // You could implement a copy constructor and copy assignment operator to
    // do a deep copy

private:
    std::unique_ptr ball;
    std::unique_ptr paddle1;
    std::unique_ptr paddle2;
    std::unique_ptr board;
};

或者,如果您确实愿意,也可以手动进行内存管理,但是这样做几乎没有好处:

class Game {
public:
    static const int BOARD_WIDTH = 60;
    static const int BOARD_HEIGHT = 12;

    Game()
        : ball{new Ball(-1, 1, BOARD_WIDTH / 2, BOARD_HEIGHT / 2)},
          paddle1{new Paddle(4, BOARD_HEIGHT / 2, 3)},
          paddle2{new Paddle(BOARD_WIDTH - 4, BOARD_HEIGHT / 2, 3)},
          board{new Board()}
    {}

    // You must implement these yourself to do a deep copy when doing manual
    // memory management.  I've opted to delete them to disallow copying a Game object
    Game(const Game&) = delete;
    Game& operator=(const Game&) = delete;

    ~Game() {
        // every instance of 'new' must have exactly one matching 'delete'
        delete board;
        delete paddle2;
        delete paddle1;
        delete ball;
    }

private:
    Ball* ball;
    Paddle* paddle1;
    Paddle* paddle2;
    Board* board;
};


推荐阅读
  • 深入解析 iOS Objective-C 中的对象内存对齐规则及其优化策略
    深入解析 iOS Objective-C 中的对象内存对齐规则及其优化策略 ... [详细]
  • 本文深入探讨了 MXOTDLL.dll 在 C# 环境中的应用与优化策略。针对近期公司从某生物技术供应商采购的指纹识别设备,该设备提供的 DLL 文件是用 C 语言编写的。为了更好地集成到现有的 C# 系统中,我们对原生的 C 语言 DLL 进行了封装,并利用 C# 的互操作性功能实现了高效调用。此外,文章还详细分析了在实际应用中可能遇到的性能瓶颈,并提出了一系列优化措施,以确保系统的稳定性和高效运行。 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在稀疏直接法视觉里程计中,通过优化特征点并采用基于光度误差最小化的灰度图像线性插值技术,提高了定位精度。该方法通过对空间点的非齐次和齐次表示进行处理,利用RGB-D传感器获取的3D坐标信息,在两帧图像之间实现精确匹配,有效减少了光度误差,提升了系统的鲁棒性和稳定性。 ... [详细]
  • 本文详细探讨了C语言中`extern`关键字的简易编译方法,并深入解析了预编译、`static`和`extern`的综合应用。通过具体的代码示例,介绍了如何在不同的文件之间共享变量和函数声明,以及这些关键字在编译过程中的作用和影响。文章还讨论了预编译过程中宏定义的使用,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • MongoDB Aggregates.group() 方法详解与编程实例 ... [详细]
  • Android ListView 自定义 CheckBox 实现列表项多选功能详解
    本文详细介绍了在Android开发中如何在ListView的每一行添加CheckBox,以实现列表项的多选功能。用户不仅可以通过点击复选框来选择项目,还可以通过点击列表的任意一行来完成选中操作,提升了用户体验和操作便捷性。同时,文章还探讨了相关的事件处理机制和布局优化技巧,帮助开发者更好地实现这一功能。 ... [详细]
  • 本文深入解析了如何通过自定义 ViewGroup 实现类似支付宝风格的酷炫雷达脉冲动画效果。文章详细介绍了自定义 ViewGroup 的原理和实现步骤,并结合实际案例展示了如何在 Android UI 设计中应用这一技术,为开发者提供了宝贵的参考和实践指导。 ... [详细]
  • 本文探讨了在Android应用中实现动态滚动文本显示控件的优化方法。通过详细分析焦点管理机制,特别是通过设置返回值为`true`来确保焦点不会被其他控件抢占,从而提升滚动文本的流畅性和用户体验。具体实现中,对`MarqueeText.java`进行了代码层面的优化,增强了控件的稳定性和兼容性。 ... [详细]
  • JavaScript最初并非设计为纯粹的面向对象编程(OOP)语言,因为直到ES5标准中仍未引入类的概念。然而,随着ES6的发布,JavaScript正式引入了类的语法,使得开发者能够更加直观地实现继承机制。本文将深入探讨JavaScript中多样的继承实现方法,包括原型链、寄生组合式继承等技术,并分析它们的优缺点及适用场景。 ... [详细]
  • 本文详细解析了 MySQL 5.7.20 版本中二进制日志(binlog)崩溃恢复机制的工作流程。假设使用 InnoDB 存储引擎,并且启用了 `sync_binlog=1` 配置,文章深入探讨了在系统崩溃后如何通过 binlog 进行数据恢复,确保数据的一致性和完整性。 ... [详细]
  • 探讨String参数作为锁对象时,实际锁定的是哪个具体实例? ... [详细]
  • 从 Java 过渡到 Ruby,不仅是一次编程语言的转换,更是一段技术进阶的旅程。本文将深入探讨两种语言在语法、生态系统和开发模式上的差异,帮助开发者顺利实现转型,并在新的环境中高效地编写高质量代码。 ... [详细]
  • 本文将介绍一种扩展的ASP.NET MVC三层架构框架,并通过使用StructureMap实现依赖注入,以降低代码间的耦合度。该方法不仅能够提高代码的可维护性和可测试性,还能增强系统的灵活性和扩展性。通过具体实践案例,详细阐述了如何在实际开发中有效应用这一技术。 ... [详细]
  • C++20 引入了指定初始化器(Designated Initializers),这一特性借鉴了 C# 的对象初始化器和 Kotlin 的 apply 范围函数。指定初始化器允许开发者在初始化结构体或类时,直接指定成员变量的值,提高了代码的可读性和简洁性。此外,该特性还支持嵌套初始化,使得复杂对象的初始化更加直观和灵活。本文将详细解析指定初始化器的语法、应用场景及其实现细节,并通过具体示例展示其在实际开发中的优势。 ... [详细]
author-avatar
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有