【发布时间】:2016-06-20 22:10:34
【问题描述】:
首先,我有下面的类A,同时还有一个嵌套类B:
// A.h
class A {
public:
class B;
A();
A(const A& a); // Copy constructor
B& operator[](const unsigned int& a) const;
A operator+(const A& a) const;
/*...*/
~A();
private:
/*...*/
unsigned int size;
B* b;
};
我正在尝试使用重载的+ 运算符通过添加所述对象的两个b 成员的内容来“添加”两个A 对象,并将结果分配给第三个A 对象.
b是一个动态分配的B对象数组。B是一个非常基础的类,只有一些unsigned int
这里是主要功能:
// main.cpp
int main(int argc, char** argv) {
A a1, a2, result;
a1.read(argv[1]); // Initialize b member with content read from a file
a2.read(argv[2]); // Initialize b member with content read from a file
result = a1 + a2; // Error [3]
getchar();
return 0;
}
问题是,当我尝试求和时,我得到了我认为的内存错误,例如:HEAP[main.exe]: Invalid address specified to RtlValidateHeap( 00A50000, 00A59938 )
这是A类的实现:
// A.cpp
A::A() : /*...*/, size(0), b(nullptr) {}
// Copy constructor
A::A(const A& a) : /*...*/, size(a.size), b(nullptr) {
b = new B[size]; // [1]
for (unsigned int i = 0; i < size; i++) {
(*this)[i] = a[i];
}
}
A::B& A::operator[](const unsigned int& i) const {
return b[i];
}
A A::operator+(const A& a) const {
if (size != a.size) {
exit(1); // Size must be the same on both operands
}
A tmp(*this); // Call to copy constructor
for (unsigned int i = 0; i < a.size; i++) {
tmp[i] += a[i];
}
return tmp; // Call to copy constructor [2]
}
A::~A() {
if (b != nullptr) {
delete[] b;
}
}
类B:
// B.h
class A::B {
public:
B();
B(unsigned char, unsigned char, unsigned char);
B& operator+=(const B& b);
private:
unsigned int a, b, c, d;
};
// B.cpp
A::B::B() : a(0), b(0), c(0), d(0) {}
A::B::B(unsigned char _a, unsigned char _b, unsigned char _c) {
/*...*/
}
A::B& A::B::operator+=(const B& b) {
/*...*/
return *this;
}
顺便说一句,我正在使用 Visual Studio,在调试时我观察到:
result的成员result指向[1] 中b指向的同一地址,当[ 中的return 语句调用复制构造函数时2],到目前为止一切顺利直到在[2]中返回
b的内容就可以了,比如:0x00669968 00 00 ff 00 00 ff 00 00 ..ÿ..ÿ..在 [3] 之后 [1] 中
b的内容,因此result对象的b成员的内容变成了什么like:0x00669968 dd dd dd dd dd dd dd dd ÝÝÝÝÝÝÝÝ,我猜是垃圾
注意:所有include 指令和不相关的代码部分都已被省略
我已经连续两天摇头试图找出没有运气的问题所以非常感谢任何帮助,在此先感谢。
【问题讨论】:
-
我看到的问题是,当
a和this具有不同的大小时,它在函数A A::operator+(const A& a) const中,您将读取无效地址。您需要限制两个 A 对象的大小必须相等。 -
可以添加
class B的定义。 -
@chema989 感谢您的帮助,尽管我所做的每次尝试都使用相同大小的对象,无论如何我已经更新了具有该限制的代码以反映您所说的内容并添加了类的定义
B -
您应该在创建
tmp对象之前验证this->size != a.size。img.size应该是a.size。但更重要的是,A::read()是如何操作b数组的?您可能在调用operator+之前损坏了数组。另外,另外,operator+应该在A内部实现为operator+=(就像你对B::operator+=所做的那样,然后你应该定义一个单独的非成员operator+来添加两个@ 987654366@s 一起。
标签: c++ copy-constructor