我有以下用于实现Bucket
类的文件。但是我不能销毁s 产生_str
的 s 的析构函数中的成员。我得到的错误是:Bucket
operator+
在正常块后检测到堆损坏...CRT 检测到应用程序在堆缓冲区结束后写入内存
添加两个对象后总是会出现问题Bucket
,但是我在调试过程中检查了生成的字符串以及长度是否正确。
另外,如何访问函数中的_len
属性operator>>
以分配新值?
头文件:
class Bucket
{
friend ostream& operator<<(ostream& os, const Bucket& c);
friend istream& operator>>(istream& is, const Bucket& c);
public:
Bucket();
Bucket(const String& str);
Bucket(const char* str);
~Bucket();
const Bucket operator+(const Bucket& s) const;
const Bucket operator+(const char* s) const;
const Bucket& operator=(const char* c);
const bool operator==(const char* str);
private:
char* _str;
int _len;
};
源文件:
Bucket::Bucket() {
_len = 0;
_str = new char[_len];
}
Bucket::Bucket(const Bucket& myBucket) {
_len = myBucket._len;
_str = new char[_len + 1];
for (int i = 0; i < _len; i++)
_str[i] = myBucket._str[i];
_str[_len] = '\0';
}
Bucket::Bucket(const char* str) {
_len = 0;
for (int i = 0; str[i] != '\0'; i++) _len++;
_str = new char[_len + 1];
for (int i = 0; i < _len; i++)
_str[i] = str[i];
_str[_len] = '\0';
}
Bucket::~Bucket() {
if (_len > 0) delete[] _str;
}
const Bucket Bucket::operator+(const Bucket& myBucket) const {
String tempBucket;
tempBucket._str = strcat(this->_str, myBucket._str);
int len = 0;
while (tempBucket._str[len] != '\0') len++;
tempBucket._str[len] = '\0';
tempBucket._len = len;
return tempBucket;
}
const Bucket Bucket::operator+(const char* str) const {
Bucket tempBucket;
int len = 0;
tempBucket._len = this->_len;
for (int i = 0; str[i] != '\0'; i++) tempBucket._len++;
tempBucket._str = strcat(tempBucket._str, str);
tempBucket._str[len] = '\0';
tempBucket._len = len;
return tempBucket;
}
const Bucket& Bucket::operator=(const char* str) {
if (this->_str == str) {
return *this;
}
_len = 0;
for (int i = 0; str[i] != '\0'; i++) _len++;
_str = new char[_len + 1];
for (int i = 0; i < _len; i++)
_str[i] = str[i];
_str[_len] = '\0';
return *this;
}
const bool Bucket::operator==(const char* str) {
int comp = strcmp(this->_str, str);
if (comp == 0) {
return true;
}
else {
return false;
}
}
ostream& operator<<(ostream& os, const Bucket& myBucket) {
os << myBucket._str;
return os;
}
istream& operator>>(istream& is, const Bucket& myBucket) {
static char buffer[40];
is >> buffer;
int len = 0;
for (size_t i = 0; buffer[i] != '\0'; i++) {
myBucket._str[i] = buffer[i];
len++;
}
myBucket._str[len++] = '\0';
return is;
}
主要的:
int main()
{
Bucket b1("Hello, "); // This is deleted by the destructor
Bucket b2(b1); // This is deleted by the destructor
cout << b1 << b2 << endl;
b2 = "Dear "; // Also works fine
Bucket b3;
cout << "Enter a name: ";
cin >> b3; // Can't assign the _len attribute
cout << b2 + b3 << ","; // not destroyed
Bucket b4(" Please write this sentence after pressing enter:\n");
b2 = "We believe that ";
cout << b4 + b2 << b1 << "and " << "Goodbye " // not destroyed
<< (b1 == "Goodbye " ? "is " : "is not ") << "the same word!\n" <<
endl;
return 0;
}
Bucket
我发现您的代码实现方式存在很多问题:
的第二个参数operator>>
必须是对非常量对象的引用,否则操作员在从istream
.
根据 3/5/0的规则,缺少复制构造函数和复制赋值运算符,最好还缺少移动构造函数和移动赋值运算符。
默认构造函数使用 分配内存new[]
,但由于_len
为 0,因此析构函数不会释放该内存。您需要_len > 0
在调用时删除检查delete[]
。
默认构造函数不会像其他构造函数那样以空值终止分配的数组。
operator+
按值返回一个新Bucket
对象(应该如此),因此将该对象标记为多余的。const
与返回的bool
相同。operator==
但是,它operator
本身应该被标记为const
,因为它不会修改Bucket
它被调用的对象。
两者operator+
都使用strcat()
不正确。重载正在修改的Bucket
内容this->str_
,它不应该这样做,更糟糕的是,this->_str
无论如何都没有重新分配以增加其附加myBucket._str
. char*
重载与tempBucket.str_
. 您需要char[]
为每个tempBucket
.
的Bucket
重载operator+
声明tempBucket
为 asString
而不是 as Bucket
。
operator=
通过引用返回修改后的Bucket
对象(应该如此),但该对象不应标记为.const
Bucket
没有公开_str
从外部代码访问其成员的方法,因此if (this->_str == str)
签入operator==
永远不会是真的。
operator=
不是在用新的替换delete[]
旧的内存之前。_str
char[]
operator>>
没有对它读入的内容执行任何边界检查buffer
。并且它没有重新分配myBucket._str
以适应buffer
. 而且,它正在计算 中的空终止符_len
,这是其他类方法都没有的。
综上所述,尝试更多类似的东西:
class Bucket
{
friend ostream& operator<<(ostream& os, const Bucket& rhs);
friend istream& operator>>(istream& is, Bucket& rhs);
public:
Bucket(size_t len = 0);
Bucket(const Bucket& src);
Bucket(Bucket&& src);
Bucket(const char* str);
Bucket(const char* str, size_t len);
~Bucket();
Bucket operator+(const Bucket& rhs) const;
Bucket operator+(const char* str) const;
/*
Bucket& operator=(const Bucket& rhs);
Bucket& operator=(Bucket&& rhs);
Bucket& operator=(const char* str);
*/
Bucket& operator=(Bucket rhs);
bool operator==(const Bucket& rhs) const;
bool operator==(const char* rhs) const;
private:
char* _str;
size_t _len;
void swap(Bucket &other);
bool equals(const char* str, size_t len) const;
Bucket concat(const char* str, size_t len) const;
};
static size_t my_strlen(const char* str) {
const char* start = str;
if (str) while (*str != '\0') ++str;
return (str - start);
}
Bucket::Bucket(size_t len) {
_len = len;
if (len > 0) {
_str = new char[len + 1];
_str[len] = '\0';
}
else {
_str = nullptr;
}
}
Bucket::Bucket(const Bucket& src)
: Bucket(src._str, src._len) { }
Bucket::Bucket(Bucket&& src) : Bucket(0) {
src.swap(*this);
}
Bucket::Bucket(const char* str)
: Bucket(str, my_strlen(str)) { }
Bucket::Bucket(const char* str, size_t len) : Bucket(len) {
if (str && len > 0) {
for(size_t i = 0; i < len; ++i) {
_str[i] = str[i];
}
}
}
Bucket::~Bucket() {
delete[] _str;
}
void Bucket::swap(Bucket &other) {
char *ptmp = _str;
_str = other._str;
other._str = ptmp;
size_t itmp = _len;
_len = other._len;
other._len = itmp;
}
bool Bucket::equals(const char* str, size_t len) const {
if (this->_len != len) return false;
for(size_t i = 0; i < len; ++i) {
if (this->_str[i] != str[i]) return false;
}
return true;
}
Bucket Bucket::concat(const char* str, size_t len) const {
Bucket tempBucket(this->_len + len);
for(size_t i = 0; i < this->_len; ++i) {
tempBucket._str[i] = this->_str[i];
}
for(size_t i = this->_len, j = 0; j < len; ++i, ++j) {
tempBucket._str[i] = str[j];
}
return tempBucket;
}
Bucket Bucket::operator+(const Bucket& rhs) const {
return concat(rhs._str, rhs._len);
}
Bucket Bucket::operator+(const char* rhs) const {
return concat(rhs, my_strlen(rhs));
}
/*
Bucket& Bucket::operator=(const Bucket& rhs) {
if (this != &rhs) {
Bucket(rhs).swap(*this);
}
return *this;
}
Bucket& Bucket::operator=(Bucket&& rhs) {
Bucket(std::move(rhs)).swap(*this);
return *this;
}
Bucket& Bucket::operator=(const char* rhs) {
Bucket(rhs).swap(*this);
return *this;
}
*/
Bucket& Bucket::operator=(Bucket rhs) {
rhs.swap(*this);
return *this;
}
bool Bucket::operator==(const Bucket& rhs) const {
return equals(rhs._str, rhs._len);
}
bool Bucket::operator==(const char* rhs) const {
return equals(rhs._str, my_strlen(rhs));
}
ostream& operator<<(ostream& os, const Bucket& rhs) {
os.write(rhs._str, rhs._len);
return os;
}
istream& operator>>(istream& is, Bucket& rhs) {
/*
string buffer;
is >> buffer;
rhs = buffer.c_str();
return is;
*/
char buffer[40];
if (!is.get(buffer, 40)) buffer[0] = '\0';
rhs = buffer;
return is;
}
话虽如此,如果您可以使用标准 C++ 功能,例如std::string
,那么代码就会变得简单得多:
#include <string>
class Bucket
{
friend ostream& operator<<(ostream& os, const Bucket& rhs);
friend istream& operator>>(istream& is, Bucket& rhs);
public:
Bucket() = default;
Bucket(const Bucket& src) = default;
Bucket(Bucket&& src) = default;
~Bucket() = default;
Bucket(const std::string& str);
Bucket operator+(const Bucket& rhs) const;
Bucket& operator=(const Bucket& rhs) = default;
Bucket& operator=(Bucket&& rhs) = default;
bool operator==(const Bucket& rhs) const;
private:
std::string _str;
};
Bucket::Bucket(const std::string str) : _str(str) { }
Bucket Bucket::operator+(const Bucket& rhs) const {
return Bucket(this->_str + rhs._str);
}
bool Bucket::operator==(const Bucket& rhs) const {
return (this->_str == rhs._str);
}
ostream& operator<<(ostream& os, const Bucket& rhs) {
os.write << rhs._str;
return os;
}
istream& operator>>(istream& is, Bucket& rhs) {
is >> rhs._str;
return is;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句