这是我明天在CS低级课程中期考试的一个问题。不幸的是,练习考试没有完全正确的解决方案;该问题中显示的具体问题已经获得了a),b)和c)部分中每个部分的半信用。
问题是为什么他们只得到半信用;如果您可以对问题的一个或所有部分发布完整的解决方案,那将会产生巨大的价值。
问题如下:
请考虑一个代表建筑工人的普通类的摘录。
class Worker
{
public:
Worker(string nm, string s)
: m_name(nm), m_skill(s)
{}
string name() const { return m_name; }
string skill() const { return m_skill; }
private:
string m_name;
string m_skill;
};
因为我们没有为Worker类声明析构函数,复制构造函数或赋值运算符,所以编译器会为我们编写这些函数。
施工人员是工人的集合。我们选择将工作人员表示为动态分配给工人的指针数组。这是一段摘录:
class Crew
{
public:
Crew(int lim)
: m_size(0), m_maxCrewSize(lim)
{
m_crew = new Worker*[lim];
}
void hire(string nm, string s)
{
if (m_size < m_maxCrewSize)
{
m_crew[m_size] = new Worker(nm, s);
m_size++;
}
}
// other functions not shown
private:
Worker** m_crew;
int m_size;
int m_maxCrewSize;
};
m_crew数组的第一个m_size元素包含指向动态分配的worker的指针;剩下的元素没有特别的价值。
Crew类的用户需要复制Crew对象并将一个Crew对象分配给另一个。
对于下面的a,b和c部分,如果愿意,可以实现其他Crew类辅助函数。不要对Worker类进行任何更改或添加。
一个。
完成Crew类的析构函数的实现:
Crew::~Crew()
{
for (int i=0; i<m_size; i++) {
delete m_crew[i];
}
}
湾实现Crew类的复制构造函数。
Crew::Crew(const Crew& original)
: m_size(original.m_size), m_maxCrewSize(original.m_maxCrewSize)
{
m_crew = new Worker*[m_maxCrewSize];
for (int i=0; i < m_size; i++) {
m_crew[i] = original.m_crew[i];
}
}
℃。为Crew类实现赋值运算符。
Crew& Crew::operator=(const Crew& other) {
if (this != &other) {
Crew temp(*this);
m_crew = other.m_crew;
m_size = other.m_size;
m_maxCrewSize = other.m_maxCrewSize;
other.m_crew = temp.m_crew;
other.m_maxCrewSize = temp.m_maxCrewSize;
other.m_size = temp.m_size;
}
return this;
}
答案 0 :(得分:1)
other
分配到this
,还会从this
分配到other
。这对于赋值运算符来说完全出乎意料,因为other
是const
,它甚至都不会编译。答案 1 :(得分:1)
虽然@quetzalcoatl是正确的,你应该问谁标记问题为什么他们这样标记,这里有一些提示:
一个。此答案无法删除m_crew
数组。结果,内存将泄漏。
湾在这个答案中,工人自己不会被复制。当新副本或原始Crew
对象的析构函数运行时,程序将崩溃,原因是双delete
。
℃。这个答案是完全错误的。我不知道为什么有人会给它半分;我什么都没有。首先,您无法写信other
,因为它是const
。其次,不应该写入other
,因为赋值运算符用于赋值,不是交换。第三,你不能像这样分配m_crew
,因为它会因为双delete
而导致崩溃。