【发布时间】:2019-11-03 17:09:12
【问题描述】:
我刚刚编写了我的第一个复制构造函数和复制运算符,我正在尝试将一个对象实例分配给一个数组,如下所示:
Agent agent = Agent(navmesh, rb, m_maxPathSize);
Agent tmp = agent; // DEBUG
m_agents[idx] = agent;
复制构造函数似乎工作正常,因为tmp 是agent 的完美副本(带有新分配的m_path 指针)。但是当我将agent 分配给m_agents[idx] 时,后者包含了我对默认构造函数的期望(m_path == 0、m_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