我应该使用公共指针吗?

时间:2013-07-29 06:31:09

标签: c++ class pointers

我目前正在制作一个游戏,我有几个类,每个类都处理自己的游戏对象。为了让这些类实际上代表游戏中的某些东西,他们需要使用另一个类,即animation_manager。 animation_manager处理在屏幕上加载,绘制和移动对象,并在启动时创建。

将经理传递给处理游戏对象的类最聪明的方法是什么?

是否应该通过公共指针完成,将其分配给每个游戏对象继承的对象类中的静态指针,或者我只是将其作为指向gameobjects / objects类构造函数的指针传递?

我正在使用C ++ 03,因此没有新的花哨修复:P

编辑1:

有很多好的建议,我很感激。 现在我不会使用弱指针,因为我不需要对象处理程序来处理指针的删除,因为它将从程序的开头到结尾存在。 单身人士不适合我的需要,因为我不希望任何课程有权使用它。

阅读回复时想到的一件事是:为所有处理类继承的static reference中的anim_handler创建Object class是否是个好主意?

7 个答案:

答案 0 :(得分:0)

您可以将此共享管理器对象保存在共享指针中,该指针将添加到C ++ 11(或者您可以使用Boost库)标准shared_ptr

它有一个引用计数机制,这样您就不必担心相关对象的所有权和内存管理。

每个gameobject都可以将共享指针成员保留到animation_manager

答案 1 :(得分:0)

我更喜欢传递构造函数。

这样你可以建立一个不变量(即经理总是存在),而后来设置一个字段并不能确保它始终完成。

就像刚发布的托马斯一样,你应该使用shared_ptr或类似的东西(如果没有使用C ++ 11)。

我尽量不使用静态字段(常量除外),因为它会阻止您为每个游戏对象使用不同的管理器对象。 (想想一下调试/日志记录管理器类或其他包装管理器)。

答案 2 :(得分:0)

如果你的animator_manager是一个唯一的对象,另一种方法可能是将它定义为一个signleton,最终不需要在gameobjects处理类中存储对它的任何引用,并使用某种静态方法,如animation_manager :: getInstance()使用它。

通过减少对getInstance()方法的调用,可以轻松地降低性能影响,但这实际上取决于您的设计,不能确定它是否合适。

答案 3 :(得分:0)

你应该把它作为参考(如果可能的话,引用const),而不是指针。只有当你有一个动画管理器的类层次结构时,一个指针(如果可能的话const到const)才有意义。在后一种情况下,您应该考虑使用boost shared_ptr。如果稍后转到C ++ 11,对C ++ 11的shared_ptr的更改是最小的。

从设计的角度来看,您可能还会考虑使用观察者模式,因此动画管理器可以在适当的时候进行渲染,而不需要太多的样板代码。

答案 4 :(得分:0)

在考虑成为优秀的软件架构师时,传递引用将是最有利的方式,因为它将允许更容易的测试和模拟。

然而,在我看来,游戏(引擎)是一个特殊的软件案例,其中“好的模式”有时会适得其反。几乎总是会遇到你需要一些经理课程的情况。

您可能希望查看神对象反模式,以使全球所有常见经理都可用。我使用一个(!)全局可访问的“Application”实例实例,它包含一些引导代码和对最常见管理器类的引用,如下所示:

// application.h
class CApplication {
    void init(int argc, char **argv); // init managers & co here 
    void shutdown();
    void run();

    CMemoryManager * memory;
    CSystemManager * system;
    CAudioManager  * sound;
    CInputManager  * input;
};

// globals.h
CApplication * app;


// main.c
#include "globals.h"
int main(int argc, char ** argv) {
    app = new CApplication();
    app->init(argc, argv);
    app->run();
    app->shutdown();
    return 0;
}

// some_other_file.cpp
#include "globals.h"

void doSomething() {
    // ...
    app->input->keyDown(...);
    // ...
}

风格不好?大概。它有用吗?对我来说确实如此。反馈也欢迎评论!

答案 5 :(得分:0)

我正在添加另一个答案,因为与之前的方法相比,这是一种完全不同的方法。 首先,我应该澄清一点,我没有游戏编程的经验! :) 无论如何,正如我在之前的评论中所建议的那样,也许,我会采取不同的方式。想象你有一个带有墙壁和其他静态元素的“游戏场”,以及一些“演员”,如怪物,玩家改变自我等等...... 我可能会写一个祖先“演员”,主要是“玩家”和“敌人”类,然后将“敌人”子类化为“龙”,“僵尸”,“鳄鱼”等等。也许演员可以有一个共同的属性,如“位置”,“速度”,“强度”,“能量”,“方向”,“目的地”和状态,说“移动”,“睡觉”,“吃”玩家“,”被吃掉“...... 一个典型的游戏迭代,可能是这样的:

1)从播放器获取输入

2)调用玩家actor对象的方法,如:

player->move(east, fast);

3)循环通过一个演员列表来更新他们的状态,比如说:

for (int i(0); i < enemies.size(); i++) {
    // Checks the player position in the gamefield and setup a strategy to eat him
    enemies[i]->updateStatus(player, gamingField);
}

4)循环通过演员列表并移动它们:

animator->animate(player);
for (int i(0); i < enemies.size(); i++) {
    animator->animate(enemies[i]);
}

5)检查是否发生了有趣的事情(玩家被鳄鱼吃掉了)

我的意思是:这是一种完全不同的方法,但我认为隔离演员逻辑可能是一个好主意,你可以完全避免原来的问题。

答案 6 :(得分:0)

在我看来,这个问题没有明确的答案,而是多种方式,每个人都有自己的意见。 如果其他人有同样的问题,我将在下面列出:

<强> Shared_Pointer: 此方法将跟踪指向地址的已使用指针的数量,如果该计数达到零,则它将释放内存。可在C ++ 11和boost库中使用。 共享指针可以像普通指针一样传递给其他对象。

建议ogni42

由构造函数传递: 指针或引用可以在构造时传递给对象。使用引用的好处是程序员不会在指针上意外使用delete

首选Onur。

使用单身人士 Singletons是一个唯一的extern类,它包含一个指向对象的指针,可以通过函数访问该对象。

这是由Albert

提出的

全局变量 只是一个全局声明的变量。就个人而言,我不推荐这些,因为它们可能变得一团糟,因为它们甚至可以从您不需要它们的代码中获得。

PanCake先生建议

静态变量 这就是我最终使用的。我这样做只有从Object类继承的对象才能访问anim_handler。我这样做的方法是声明Object我的anim_handler的朋友,然后我创建静态变量来检索处理程序protected

无论如何,感谢大家的支持!我很欣赏它,我甚至学到了新东西! :)