簡體   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