【问题标题】:I can't assign an object to an object array我无法将对象分配给对象数组
【发布时间】:2019-11-03 17:09:12
【问题描述】:

我刚刚编写了我的第一个复制构造函数和复制运算符,我正在尝试将一个对象实例分配给一个数组,如下所示:

Agent agent = Agent(navmesh, rb, m_maxPathSize);
Agent tmp = agent; // DEBUG
m_agents[idx] = agent;

复制构造函数似乎工作正常,因为tmpagent 的完美副本(带有新分配的m_path 指针)。但是当我将agent 分配给m_agents[idx] 时,后者包含了我对默认构造函数的期望(m_path == 0m_alive == false)。

我的构造函数如下所示:

Agent() { m_path = 0; m_alive = false; };
Agent::Agent(NavMeshNavigator* navmesh, RigidBody* rb, int maxPathSize)
    : m_rb(rb), m_navmesh(navmesh), m_maxPathCount(maxPathSize)
{
    m_path = new float3[maxPathSize];
};
Agent::Agent(const Agent &a)
{
    memcpy(this, &a, sizeof(Agent));
    if (m_path)
    {
        float3* oldptr = m_path;
        m_path = new float3[m_maxPathCount];
        memcpy(m_path, oldptr, m_maxPathCount * sizeof(float3));
    }
}
Agent& Agent::operator=(const Agent &a) { return Agent(a); }
Agent::~Agent() { if (m_path) delete[] m_path; };

...

protected:
   float3* m_path;
   bool m_alive = true;

构造函数使用new[]m_path 分配内存,析构函数使用delete[] 释放它,复制运算符调用复制构造函数,并且复制构造函数在分配新的m_path 数组之前首先复制原始内存。

在我的测试用例中,idx == 0,所以不可能。我最初使用 malloc 而不是 new[] 但得到了相同的结果。我想说问题出在我的复制构造函数/操作符上,因为我没有这方面的经验,但是为什么它在 tmp 上完美运行?

编辑: m_agents 数组是这样声明和销毁的:

NavMeshAgents(int maxAgents, int maxAgentPathSize)
        : m_maxAgents(maxAgents), m_maxPathSize(maxAgentPathSize)
    {
        m_agents = new Agent[maxAgents];
    };
    ~NavMeshAgents() { if (m_agents) delete[] m_agents; m_agents = 0; };

【问题讨论】:

  • 你是如何声明/定义m_agents数组的?
  • 你的赋值运算符坏了。您不仅没有为其中的成员变量分配任何内容,而且还返回对临时的引用(一开始不应该编译)。你为什么要做所有这些指针杂耍呢?如果将m_path 替换为std::vector,则不需要复制构造函数和赋值以及析构函数...
  • Agent tmp = agent 不是赋值,而是复制构造函数调用。
  • @Evg Start here。我们最近在这里遇到了一些政治问题。
  • 因为不能保证对象在内存中的表示仅由其数据成员组成。例如,如果它有虚函数怎么办?请参阅此处的注释en.cppreference.com/w/cpp/types/is_trivially_copyable

标签: c++ memory copy-constructor


【解决方案1】:

正如@Evg @HolyBlackCat 和@Adrian-Reinstate-Monica 在cmets 中解释的那样,new[] 为其所有成员调用默认构造函数。 Agent tmp = agent 调用复制构造函数,而tmp = agent 将调用赋值运算符 (tmp.operator=(agent))。我的赋值运算符错了,它应该初始化this(然后返回*this而不是返回一个实例。

【讨论】:

  • 它返回*this 以方便链接a = b = c,模仿基本类型。如果不需要,operator=可以声明为void operator=(...)
猜你喜欢
  • 1970-01-01
  • 2011-06-06
  • 2010-11-22
  • 2017-12-10
  • 1970-01-01
  • 1970-01-01
  • 2019-12-06
  • 2019-10-20
  • 2015-07-15
相关资源
最近更新 更多