1

私はこのプログラミングのことは得意だと思っていましたが、私の教科書には (都合の良いことに) 欠けているウォークスルーという悪魔に出会うまでは。

私の推測では、コピー コンストラクターに関するものです。

ParagraphWordの 2 つのクラスが含まれます。各Paragraphクラス内には、 Wordオブジェクトの動的配列があります。問題は、Paragraph クラス += 演算子のオーバーロード メソッドが main() で呼び出されるときです。教授は、 Wordコンストラクターを呼び出し、次にWord = 演算子 を呼び出すとコメントしています。

私が間違っている場合は修正してください。ただし、左側のWordオブジェクトと右側の文字列を処理する別の演算子のオーバーロードがあるべきではありませんか??

#include <iostream>
 using namespace std;
 #define WIDTH 8

 class Word {
     char* text;
     int nletters;
   public:
     Word() {
         text = NULL;
         nletters = 0;
         cout << 'W';
     }
     Word(const char* s) {
         nletters = 0;
         while(s[nletters] != '\0')
             nletters++;
         text = new char[nletters];
         for (int i = 0; i < nletters; i++)
             text[i] = s[i];
         cout << 'X';
     }
     Word(const Word& p) {
         text = NULL;
         *this = p;  // calls assignment operator below
         cout << 'Y';
     }
     ~Word() {
         if (text != NULL) delete [] text;
         cout << "~W" << nletters;
     }
     Word& operator=(const Word& p) {
         if (this != &p) {
             if (text != NULL) delete [] text;
             nletters = 0;
             if (p.text != NULL) {
                 text = new char[p.nletters];
                 while(nletters < p.nletters) {
                     text[nletters] = p.text[nletters];
                     nletters++;
                 }
             }
             else
                 text = NULL;
         }
         cout << 'V';
         return *this;
     }
     int nLetters() const { return nletters; }
     friend ostream& operator<<(ostream& os, const Word& w) {
         if (w.text != NULL)
             for (int i = 0; i < w.nletters; i++)
                 os << w.text[i];
         else
             os << "***";
         os << ' ';
         return os;
     }
 };

 class Paragraph {
     Word* word;
     int mwords;
     int nwords;
     int width;
   public:
     Paragraph() {
         word  = NULL;
         width = WIDTH;
         nwords = 0;
         mwords = 0;
         cout << 'P' << endl;
     }
     Paragraph(const Paragraph& c) {
         word  = NULL;
         *this = c;  // calls assignment operator below
         cout << "cP";
     }
     Paragraph& operator=(const Paragraph& c) {
         if (this != &c) {
             if (word != NULL) delete [] word;
             if (c.word != NULL) {
                 word = new Word[c.mwords];
                 cout << endl;
                 for (int i = 0; i < c.nwords; i++)
                     word[i] = c.word[i];  // calls Word assignment operator
             }
             else
                 word = NULL;
             width  = c.width;
             nwords = c.nwords;
             mwords = c.mwords;
         }
         cout << "=P";
         return *this;
     }
     ~Paragraph() {
         if (word != NULL) delete [] word;
         cout << '\n' << nwords << "~P" << endl;
     }
     void make(int m) {
         if (word == NULL) {
             word = new Word[m];
             mwords = m;
             nwords = 0;
             width  = WIDTH;
         }
     }
     void setWidth(int w) { width = w; }
     friend ostream& operator<<(ostream& os, const Paragraph& p) {
         int nextWord = 0;
         for (int i = 0; i < p.nwords; i++) {
             if (nextWord + p.word[i].nLetters() > p.width) {
                 os << '\n';
                 nextWord = 0;
             }
             cout << p.word[i];
             nextWord += p.word[i].nLetters() + 1;
         }
         return os;
     }
     Paragraph& operator+=(const char* w) {
         if (nwords < mwords) {
             cout << "\n+=";
             word[nwords] = w;  // calls Word constructor, then Word = operator
             nwords++;
         }
         return *this;
     }
 };

 int main() {

     Paragraph p;
     cout << "--------\n";
     p.make(5);
     p += "This";
     p += "is";
     p += "hard";
     cout << "\n--------\n";
     cout << p << endl;
     cout << "--------\n";
     Paragraph q = p;
     q.setWidth(6);
     q += "too";
     cout << "\n--------\n";
     cout << q << endl;
     cout << "---------------\n";
     return 0;
 }
4

1 に答える 1

1

あなたの教授は正しいです。const char*a は aに直接 (そして暗黙的に) 変換可能であるため、別の演算子は必要ありませんWord

Word(const char* s)

これを変換コンストラクタと呼びます。として宣言するとexplicit、コンパイルされなくなります。こちらをご覧ください - http://ideone.com/brjIi

だからラインで

word[nwords] = w;

テンポラリーWordが実際に から作成されw、次に代入演算子 forWordが呼び出されてテンポラリーが に割り当てられwords[nwords]ます。

コードに関するその他の注意事項:

  • 教授が C++ を教えているので、 と について学ぶ必要がstd::stringありstd::vectorます。彼は、ポインターや動的メモリ割り当ての能力を実証するために、C++ もクラスも必要としません。
  • のようなステートメントif (word != NULL) delete [] word;は冗長です。deleteまたはポインタdelete[]上でNULL動作することが保証されています(そして何もしません)。
  • コンストラクターのロジックが間違っています (自分でメモリを管理していない場合はそうではありません)。を構築した後は、Paragraphを呼び出すまで使用できませんmake()。これは悪い設計です。
于 2012-08-16T01:22:02.287 に答える