C++ 演练困境:

C++ Walkthrough Woes:

本文关键字:困境 演练 C++      更新时间:2023-10-16

我以为我很擅长编程,直到我遇到了这个(方便)在我的教科书中没有的演练的魔鬼。

我的猜测是关于复制构造函数的。

它涉及两个类,段落单词。 每个段落类中都有一个 Word 对象的动态数组。 问题是当在main()中调用Paragraph类+=运算符重载方法时 - 一位教授评论说它调用了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] != '')
             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;
 }

你的教授是对的。您不需要其他运算符,因为const char*可以直接(隐式)转换为Word,方法是:

Word(const char* s)

这称为转换构造函数。如果你把它声明为explicit,它应该不再编译。看这里 - http://ideone.com/brjIi

所以在线

word[nwords] = w;

确实是从w创建临时Word,然后调用Word赋值运算符将临时赋值分配给words[nwords]

关于代码的其他一些说明:

  • 既然你的教授教你C++,你应该了解std::stringstd::vector。他不需要C++也不需要类来演示指针或动态内存分配的强大功能。
  • if (word != NULL) delete [] word;这样的陈述是多余的。 NULL指针上的deletedelete[]保证正常工作(并且不执行任何操作)。
  • 构造函数中的逻辑是错误的(如果您自己不管理内存,则不会)。在你构造一个Paragraph之后,它不能使用,直到你调用make(),这是糟糕的设计。