c++析构函数、复制构造函数和赋值操作符实践考试

C++ practice exam on Destructors, Copy Constructors, and Assignment Operators

本文关键字:赋值操作符 考试 构造函数 析构函数 复制 c++      更新时间:2023-10-16

这是我明天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类声明析构函数、复制构造函数或赋值操作符,所以编译器会为我们编写这些函数。

施工队是工人的集合。我们选择将crew表示为一个动态分配的指向Workers的指针数组。以下是节选:

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元素包含指向动态分配工人的指针;其余元素没有特定的值。

Crew类的用户需要复制Crew对象,并将一个Crew对象分配给另一个。

对于下面的a、b和c部分,如果您愿意,可以实现额外的Crew类辅助函数。不要对Worker类做任何更改或添加。

.

完成Crew类析构函数的实现:

Crew::~Crew()
{
  for (int i=0; i<m_size; i++) {
    delete m_crew[i];
  }
}

b。为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];
  } 
}

c。为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;
}
  1. 析构函数不释放指针数组,这意味着它泄漏。
  2. 复制构造函数不执行深度复制(这可能是预期的)
  3. 赋值操作符不仅将other赋值给this,还将this赋值给other。对于赋值操作符来说,这是完全出乎意料的,它甚至不会编译,因为otherconst

虽然@quetzalcoatl是正确的,你应该问谁标记的问题,为什么他们这样标记,这里有一些提示:

。这个答案不能删除m_crew数组。因此,内存将会泄漏。

b。在这个答案中,工人本身并没有被复制。由于双delete,当新副本或原始Crew对象的析构函数运行时,程序将崩溃。

c。这个答案是完全错误的。我不知道为什么有人会给它半分;我什么也不给。首先,您不能写入other,因为它是const。其次,不应该写入other,因为赋值操作符是用于赋值的,而不是用于交换的。第三,你不能像这样分配m_crew,因为它会导致之后的崩溃,因为双delete