c++ - 类中的所有对象都应该是引用吗?

标签 c++ include forward-declaration

总是让我的对象成员的数据类型成为引用是不好的做法吗?

看完这篇question about avoiding #include我一直在努力避免在我当前的 C++ 项目中使用#include,并始终转发声明我的数据类型。

这是我项目中的示例代码片段。在标题中我有 EnemyBuilder &m_builder;然后我在源代码中初始化它。

敌人工厂.h

#include <string>

#ifndef ENEMYFACTORY
#define ENEMYFACTORY

class World;
class Enemy;
class EnemyBuilder;

class EnemyFactory
{
private:
    EnemyBuilder &m_builder;
    World &m_world;

public:
    EnemyFactory(World &world);

    Enemy* produce(std::string type);
};

#endif

敌人工厂.cpp

#include "EnemyFactory.h"

#include "EnemyBuilder.h"
#include "World.h"
#include "Enemy.h"

EnemyFactory::EnemyFactory(World &world) :
    m_world(world), m_builder(EnemyBuilder())
{

}

Enemy* EnemyFactory::produce(std::string type)
{
    Enemy *product = new Enemy(m_world);

    if (type == "basic")
    {
        product->setSpeed(5000.0f);
    }

    return product;
}

最佳答案

Is it bad practice to always make my object member's data type a reference?

这不仅是不好的做法,而且效率低下且限制性强。

Why?

  1. 包含引用的类的对象自动不可分配。该标准具有 std::reference_wrapper<>(基本上是一个包装指针)以在将引用类型绑定(bind)到函数对象时绕过此限制。

  2. 您有义务管理对象的生命周期。由于您存储的是引用而不是对象,因此您的类无法自行清理。此外,它不能确保它所引用的对象仍然存在。你刚刚失去了 c++ 给你的所有保护。欢迎来到石器时代。

  3. 效率较低。现在,所有对象访问都通过本质上是指针的方式取消引用。而且您很可能会丢失缓存位置。毫无意义。

  4. 您失去了将对象视为值的能力。这将导致程序效率低下、复杂。

  5. 我可以继续......

What should I do?

更喜欢值语义(将对象视为值)。让它们被复制(如果你很好地编写你的类,大部分拷贝将被删除)。将它们封装并组合成更大的对象。让容器管理组件的生命周期。这是它的工作。

What about the time cost of including a few header files?

除非您在数百(数千)个模板类中进行极其复杂的模板扩展,否则它不太可能成为问题。与编译几个源文件相比,您浪费在泡咖啡上的时间更多。

关于c++ - 类中的所有对象都应该是引用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35904536/

相关文章:

c++ - 转发定义和命名空间使用

c++ - Boost Spirit X3 指定多拷贝构造函数

c++ - 模板类的模板化相等运算符不编译

c++ - 数组中两个数之和的最小差值

c - 链接和静态函数混淆

c++ - 以 API 向后兼容的方式添加新的命名空间

c++ - "Tracking"与 Thrift 的连接

asp-classic - 是否可以将主域中的虚拟文件包含在asp的子域中?

c++ - C++ 中相互包含的 header

c - 如何处理接口(interface)和实现中不完整的类型定义和前向声明