我正在尝试使用下标运算符创建从1索引的自定义数组。获取价值工作正常,但我不知道,为什么使用下标运算符分配不起作用。
class CEntry {
public:
CKey key;
CValue val;
CEntry(const CKey& key, const CValue& val) {
this->key = key;
this->val = val;
}
CEntry& operator= (const CEntry& b) {
*this = b;
return *this;
};
};
...
class EntriesArray {
public:
CEntry **entries;
int length;
EntriesArray(int length) {
this->length = length;
entries = new CEntry*[length];
int i;
for (i = 0; i < length + 1; i++) {
entries[i] = NULL;
}
};
CEntry& operator[] (const int index) {
if (index < 1 || index > length) {
throw ArrayOutOfBounds();
}
return *entries[index - 1];
};
};
以这种方式构造数组
EntriesArray a(5);
这有效
a.entries[0] = new CEntry(CKey(1), CValue(1));
cout << a[1].val.value << endl;
这不起作用
a[1] = new CEntry(CKey(1), CValue(1));
修改
使用
CEntry *operator=( CEntry *orig)
它编译okey,但gdb停在
No memory available to program now: unsafe to call malloc warning: Unable to restore previously selected frame
with backtrace
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00007fff5f3ffff8
0x00000001000013c8 in CEntry::operator= (this=0x0, orig=0x1001008d0) at /Users/seal/Desktop/efa du2_pokus2/efa du2_pokus2/main.cpp:20
20 /Users/seal/Desktop/efa du2_pokus2/efa du2_pokus2/main.cpp: No such file or directory.
in /Users/seal/Desktop/efa du2_pokus2/efa du2_pokus2/main.cpp
答案 0 :(得分:1)
起初......这个:
CEntry& operator= (const CEntry& b) {
*this = b;
return *this;
};
不应该工作(这应该导致operator=
的递归调用。
第二件事是你试图将CEntry *
分配给CEntry
,如果你有CEntry *operator=( CEntry *orig)
这会有用,但我认为这是不好的编码习惯。
答案 1 :(得分:0)
由于EntriesArray::operator[]
会返回CEntry &
,但new CEntry
会返回CEntry *
。
也许你想要a[1] = CEntry(CKey(1), CValue(1))
? (没有new
。)
顺便说一句,您当前对CEntry::operator=
的定义会导致堆栈溢出。
答案 2 :(得分:0)
此
return *entries[index - 1];
取消引用NULL指针。
您希望指针本身被a[1] = new CEntry(CKey(1), CValue(1));
覆盖,而不是指向值。
试试这个:
class EntriesArray
{
public:
int length;
CEntry **entries;
EntriesArray( int length ) : length(length), entries(new CEntry*[length]())
{
}
// defaulted special member functions are inappropriate for this class
EntriesArray( const EntriesArray& ); // need custom copy-constructor
~EntriesArray(); // need custom destructor
EntriesArray& operator=(const EntriesArray&); // need custom assignment-operator
CEntry*& operator[] (const int index) {
if (index < 1 || index > length) {
throw ArrayOutOfBounds();
}
return entries[index - 1];
}
};
答案 3 :(得分:0)
您可以尝试替换
CEntry& operator[] (const int index) {
if (index < 1 || index > length) {
throw ArrayOutOfBounds();
}
return *entries[index - 1];
};
与
void Add(const int index, CEntry *pEntry) {
if (index < 1 || index > length) {
throw ArrayOutOfBounds();
}
entries[index - 1] = pEntry;
};
但是由于你现在存储对堆上分配的对象的引用(使用new),你需要一个析构函数~EntriesArray()
来删除它们。
答案 4 :(得分:0)
继上面的评论: 为了使它能够编写新值,您可能需要这样的东西 (我没有通过一个或ptr与参考资料进行双重检查)
CEntry& operator[] (const int index) {
if (index < 1) {
throw ArrayOutOfBounds();
}
// Add default elements between the current end of the list and the
// non existent entry we just selected.
//
for(int i = length; i < index; i++)
{
// BUG is here.
// We don't actually know how "entries" was allocated, so we can't
// assume we can just add to it.
// We'd need to try to resize entries before coming into this loop.
// (anyone remember realloc()? ;-)
entries[i] = new CEntry();
}
return *entries[index - 1];
};
答案 5 :(得分:0)
此问题可能与this one有关。
我试图修复你的代码;我相信这就是你想要做的事情:
(在g ++ 5.3.0上测试此代码)
#include <iostream>
#include <stdexcept>
#include <string>
// Some implementation for CKey and CValue:
typedef int CKey;
struct CValue {
int value;
CValue(int value=0) : value(value) {}
};
class CEntry {
public:
CKey key;
CValue val;
CEntry(): key(0), val(0) {}
CEntry(const CKey& key, const CValue& val): key(key), val(val) {}
CEntry& operator= (const CEntry& b) {
this->key = b.key;
this->val = b.val;
return *this;
};
};
class EntriesArray {
public:
CEntry *entries;
int length;
EntriesArray(int length) {
this->length = length;
entries = new CEntry[length];
};
CEntry& operator[] (const int index) {
if (index < 1 || index > length) {
throw std::domain_error("out of bounds!");
}
return entries[index - 1];
};
};
int main(int argc, char* argv[]) {
using namespace std;
EntriesArray a(5);
// This works
a.entries[0] = CEntry(CKey(1), CValue(1));
cout << a[1].val.value << endl;
// This doesn't work
a[1] = CEntry(CKey(2), CValue(2));
cout << a[1].val.value << endl;
}
您也可以将a[1]
用作a[1].val.value
例如:
cout << a[1] << endl;
要执行此操作,只需将此行添加到cEntry:
operator int() { return val.value; }
我希望它有所帮助。