【问题标题】:How to Instantiate my code utilizing C++11 unique_ptr?如何使用 C++11 unique_ptr 实例化我的代码?
【发布时间】:2017-06-15 07:41:07
【问题描述】:

在我的实验游戏引擎中,我目前正在使用原始指针在堆上创建一些游戏子系统。基本上,我的派生类使用它们的构造函数来调用 base 中的受保护构造函数,该构造函数会为它们更新这些子系统。我的代码是这样的:

Entity.h(基类)

#pragma once
#include <memory>

namespace BlazeGraphics{ class Graphics; }
namespace BlazePhysics{ class Physics; }
namespace BlazeInput{ class Controller; }

namespace BlazeGameWorld
{
    class Entity
    {
    protected:
        Entity(BlazeGraphics::Graphics* renderer, BlazePhysics::Physics* physics, BlazeInput::Controller* controller);

        BlazeGraphics::Graphics* renderer;
        BlazePhysics::Physics* physics;
        BlazeInput::Controller* controller;
    };
}

Entity.cpp

#include "Graphics/Graphics.h"
#include "Input/Controller.h"
#include "Physics/Physics.h"
#include "Input/Input.h"
#include "Entity.h"

namespace BlazeGameWorld
{
    Entity::Entity()
    {}

    Entity::Entity(BlazeGraphics::Graphics* renderer, BlazePhysics::Physics* physics, BlazeInput::Controller* controller) :
        renderer(renderer),
        physics(physics),
        controller(controller),
        position(0.0f, 0.0f),
        velocity(0.0f, 0.0f)
    {
    }

    Entity::~Entity()
    {
    }
}

Player.cpp(派生)

#include "Graphics/Graphics.h"
#include "Input/Input.h"
#include "Input/PlayerController.h"
#include "Physics/Physics.h"
#include "Player.h"

namespace BlazeGameWorld
{
    Player::Player() :
        Entity(new BlazeGraphics::Graphics, new BlazePhysics::Physics, new BlazeInput::PlayerController)
    {
    }

    Player::~Player()
    {
    }
}

我将如何更新()此代码以正确利用 C++11 的 unique_ptr?我无法弄清楚如何在我的课程中正确初始化这个智能 ptr。

【问题讨论】:

  • 我会谨慎使用 unique_ptr 进行所有操作。我建议花一点时间来查看需要从整个项目设计中的不同翻译单元和类访问哪些类型的对象,对于那些符合此描述的对象,我将使用 shared_ptr 代替。现在对于一个只存在一次并且具有应用程序生命周期的对象,那么拥有该对象的 unique_ptr 是有意义的。

标签: c++ c++11 inheritance smart-pointers


【解决方案1】:

这非常容易。您只需将所有原始指针定义更改为std::unique_ptr,基本上就完成了。

std::unique_ptr<BlazeGraphics::Graphics> renderer;

唯一指针的初始化方式与初始化原始指针的方式相同。当持有它们的对象死亡时,它们将被自动删除,因此您不需要在析构函数中手动释放内存(如果您有任何delete &lt;...&gt; 语句,请删除它们)。

您也不需要更改使用指针的代码,因为它们指向的对象是使用-&gt; 运算符访问的,与原始指针相同。

【讨论】:

  • 注意语义上的差异! unique_ptr 暗示所有权,原始指针没有。如果您无法为每个新的 unique_ptr 找到对应的 delete,则可能意味着您不拥有该对象。
  • @RustyX 除非您的代码会泄漏每个对象,因为它没有删除,就像问题中的示例一样。
  • 如果您将基类构造函数的签名更改为使用unique_ptrs(您应该这样做),则基类构造函数必须在初始化时从其参数中使用std::move
  • 如果我想使用std::make_unique怎么办?我只见过直线代码中的示例,而不是像我这样的类。
  • @Jason std::make_unique 仅在 C++14 中添加。由于您的问题是关于 C++11,所以还没有这样的事情。 (每个人都在谈论make_unique,就像你可以在任何地方使用它一样,即使是在专门引用 C++11 或更早版本的问题上。)
猜你喜欢
  • 1970-01-01
  • 2016-06-27
  • 2015-04-28
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
  • 2021-01-30
  • 1970-01-01
相关资源
最近更新 更多