C++ 演练困境:
C++ Walkthrough Woes:
我以为我很擅长编程,直到我遇到了这个(方便)在我的教科书中没有的演练的魔鬼。
我的猜测是关于复制构造函数的。
它涉及两个类,段落和单词。 每个段落类中都有一个 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::string
和std::vector
。他不需要C++也不需要类来演示指针或动态内存分配的强大功能。 - 像
if (word != NULL) delete [] word;
这样的陈述是多余的。NULL
指针上的delete
或delete[]
保证正常工作(并且不执行任何操作)。 - 构造函数中的逻辑是错误的(如果您自己不管理内存,则不会)。在你构造一个
Paragraph
之后,它不能使用,直到你调用make()
,这是糟糕的设计。
相关文章:
- 理解递归代码的演练
- C++名称解析困境
- C++简单函数困境
- Bjarne Stroustrup PPP - 第 9 章 演练 4 - cout 枚举错误
- 代码 P 的问题:PP 演练 4
- 编程:原理与实践 使用C++ 第 4 章演练步骤 6:关于数字范围的一般问题
- 双重选择对数组进行排序 - 诚实地陷入困境
- 循环时我如何摆脱困境
- B/B 树的实现与使班级成为另一个班级困境的朋友有关
- C++:关于囚徒困境申请的建议
- 编程原理和实践使用C++第 4 章演练,步骤 7
- 为什么我会陷入困境?[C ]
- C++和CRTP模式的实现与编译器困境
- C++的记忆分配困境
- 使用"cin"进行演练 #7 获得不同的结果 编程:使用C++的原则和实践 (Stroustrup) 第 4 章
- 递归下降解析器,变量与自身的初始化,困境
- C++ 演练困境:
- C++指针的困境
- OpenGL纹理加载困境
- C++tron AI陷入了自己的困境