使用重载的下标运算符赋值
Assign value using overloaded subscript operator
我正在尝试使用下标运算符创建从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
带有回溯
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
起初。。。此:
CEntry& operator= (const CEntry& b) {
*this = b;
return *this;
};
不应该工作(这将导致operator=
的递归调用)。
第二件事是,您正在尝试将CEntry *
分配给CEntry
,如果您有CEntry *operator=( CEntry *orig)
,这会起作用,但我认为这是一种糟糕的编码实践。
这个问题可能与这个问题有关。
我试图修复你的代码;我相信这就是你想要做的:
(在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; }
我希望它能有所帮助。
您可以尝试替换
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()
来将它们全部删除。
因为EntriesArray::operator[]
返回CEntry &
,但new CEntry
返回CEntry *
。
也许你想要a[1] = CEntry(CKey(1), CValue(1))
?(无new
。)
顺便说一句,您当前对CEntry::operator=
的定义将导致堆栈溢出
此
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];
}
};
根据我上面的评论:为了让它与编写新的价值观相结合,你可能需要这样的东西(我还没有仔细检查过一个或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];
};
- 重载Singly Linked List中的赋值运算符
- 使用赋值运算符重载从类中返回jobject
- 标准库类型的赋值运算符的引用限定符
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 基类和派生类的多态赋值运算符
- 为用户定义的类正确调用复制构造函数/赋值运算符
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 为什么初始化时没有调用重载赋值运算符?
- 赋值运算符重载和自赋值
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- Qt PL/SQL - 赋值运算符 - 字符串缓冲区太小
- 使用 OR 运算符赋值
- 交换与使用std::map[]运算符赋值(const问题)
- 为什么派生类不使用基类运算符=(赋值运算符)?
- 如何解决VC++2012生成运算符=赋值和复制构造函数的错误
- 商运算符赋值
- 使用重载的下标运算符赋值
- 在移动运算符/赋值运算符中,我应该使用std::move还是std::forward