繁体   English   中英

以下代码是尝试实现规则 3,但我遇到了一些错误

[英]The following code is an attempt to implement the Rule of 3, but Im getting a few errors

我在这个程序中有 8 个错误。 任何人都可以帮忙吗?

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

class Name {
   const char* m_value;

   void allocateAndCopy(const char* value) {
      delete[] m_value;
      m_value = new char[strlen(value) + 1];
      strcpy(m_value, value);
   }

public:
   Name() :m_value(nullptr) {
   };

   Name(const char* value) :m_value(nullptr) {
      allocateAndCopy(value);
   }

   Name(Name& N) {
      *this = N;
   }

   Name operator=(const Name& N) {
      allocateAndCopy(N.m_value);
      return this;
   }

   ~Name() {
      delete[] m_value;
   }

   void display(ostream& os)const {
      os << m_value;
   }

   void read(istream& is) {
      char val[1000];
      getline(is, val);
      allocateAndCopy(val.c_str());
   }
};

ostream& operator<<(ostream& os, Name& N) {
   N.display(os);
   return os;
}

istream& operator<<(istream& is, Name& N) {
   return N.read(is);
}

我得到的错误是:

Severity    Code    Description Project File    Line    Suppression State
Error (active)  E0167   argument of type "const char *" is incompatible with parameter of type "char *"
and more.

显示的代码至少有四个基本错误/问题。

 strcpy(m_value, value);

m_value是一个const char * ,一个指向常量字符的指针。 当然,“常数”意味着您不能对它们进行strcpy()

与其立即将new []的结果分配给m_value ,然后将strcpy()分配到其中,不如将 new [ new []的结果存储在临时char *中,然后将strcpy() ed; 然后临时char *最终可以放入m_value

Name(Name& N) {

正确的复制构造函数应该将const引用作为参数,这应该是Name(const Name &N)

Name(Name& N) {
  *this = N;
}

此构造函数无法初始化m_value class 成员。 然后构造函数调用重载的operator= 最终,它将尝试删除从未初始化的m_value 这会导致未定义的行为,并可能导致崩溃。 您还需要修复此错误。

 Name operator=(const Name& N) {

重载的operator=应该返回对this的引用,而不是全新的 object。 这应该返回一个Name & ,实际上返回*this

你的代码有很多问题:

  • m_value是一个const char* ,即指向只读 memory 的指针,但您正在尝试修改它指向的数据(通过strcpy() ),因此它需要是一个char* ,即指向可写的指针memory。

  • allocateAndCopy()不考虑value nullptr 使用nullptr作为输入调用strlen()strcpy()未定义的行为

  • 复制构造函数在调用operator=之前没有初始化m_value ,因此使allocateAndCopy()在无效指针上调用delete[] ,这也是未定义的行为

  • operator=被声明为按值返回一个新的Name object, this是一个Name*指针。 您需要通过Name&引用返回*this 您也没有考虑自我分配的可能性(即,将Name object 分配给自身)。

  • read()正在调用std::getline() ,它需要std::string而不是char[] 并且char[]没有c_str()方法。 在将val传递给allocateAndCopy()之前,您没有检查getline()是否成功。

  • operator<<应该采用const Name&引用。

  • operator<<需要返回is 相反,它试图返回read()的返回值,即void

话虽如此,请尝试更像这样的东西:

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

class Name {
   char* m_value = nullptr;

   void allocateAndCopy(const char* value) {
      delete[] m_value;
      m_value = nullptr;
      if (value) {
          m_value = new char[strlen(value) + 1];
          strcpy(m_value, value);
      }
   }

public:
   Name() = default;

   Name(const char* value) {
      allocateAndCopy(value);
   }

   Name(const Name& N) {
      allocateAndCopy(N.m_value);
   }

   Name& operator=(const Name& N) {
      if (&N != this) {
          allocateAndCopy(N.m_value);
      }
      return *this;
   }

   ~Name() {
      delete[] m_value;
   }

   void display(ostream& os) const {
      os << m_value;
   }

   void read(istream& is) {
      char val[1000] = {};
      if (is.getline(val, 1000))
          allocateAndCopy(val);

      /* alternatively: 

      string val;
      if (getline(is, val))
          allocateAndCopy(val.c_str());
      */
   }
};

ostream& operator<<(ostream& os, const Name& N) {
   N.display(os);
   return os;
}

istream& operator<<(istream& is, Name& N) {
   N.read(is);
   return is;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM