C ++演练困境:

时间:2012-08-16 01:17:15

标签: c++ operator-overloading copy-constructor

我以为自己擅长这个编程工作,直到我在教科书中(方便地)缺少一个演练的魔鬼。

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

它涉及两个类,段落 Word 。每个段落类中都有一个动态的 Word 对象数组。问题是在main()中调用段落类+ =运算符重载方法 - 教授评论它调用 Word 构造函数,然后 Word < / em> =运算符。

如果我错了,请纠正我,但不应该有另一个操作符重载来处理左边的 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;
 }

1 个答案:

答案 0 :(得分:1)

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

Word(const char* s)

这称为转换构造函数。如果将其声明为explicit,则不应再编译。见这里 - http://ideone.com/brjIi

所以就行了

word[nwords] = w;

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

关于代码的其他一些注释:

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