您好我是一名学生,为了学习目的而开发各种抽象数据类型。我试图重写下标操作符以查找这些ADT中的键。我无法避免我的代码插入缺失密钥的情况。
当从这些ADT读取时,nullptr的返回值将指示未找到该键。我希望我的ADT只在写入或插入时添加新密钥。我的代码处理以下内容的代码不正确:
const char *x = tree["key"];
如果未找到“key”,我希望避免添加此密钥并返回nullptr以指示其不存在。只应在以下情况下添加密钥:
tree["key"] = "x";
这是一个非常微妙的错误。以下测试返回true,但仅仅是因为正在测试的值是hash [“key”]。val(恰好为null)。
if (!x) printf("%s not found!\n", "key");
我相信这可以通过使用const来实现,并使用了以下签名。
char const *operator[](char *index) const;
永远不会调用此const重载。有人可以解释为什么会出现这种情况,也可以解释一个行为正常的示例签名(或者一个会强制评估此重载的示例)。这是我的代码:
#include <stdio.h>
#include <string.h>
class lookup {
lookup *left;
lookup *right;
char *key;
char *val;
public:
lookup(char *k) {
left = nullptr;
right = nullptr;
val = nullptr;
key = new char[strlen(k)+1];
strcpy(key, k);
}
~lookup() {
if (key) delete key;
if (val) delete val;
}
/* read/write access */
/* if the key does not exist, then create it */
char *&operator[](char *index) {
printf(" []= x\n");
int x = strcmp(index, key);
if (x < 0) {
if (left == nullptr) left = new lookup(index);
return (*left)[index];
}
if (x > 0) {
if (right == nullptr) right = new lookup(index);
return (*right)[index];
}
return val;
}
/* read only access */
/* if the key does not exist, then return nullptr (not found) */
char const *operator[](char *index) const {
printf(" x = *[]\n");
int x = strcmp(index, key);
if (x < 0) {
if (left == nullptr) return nullptr;
else return (*left)[index];
}
if (x > 0) {
if (right == nullptr) return nullptr;
else return (*right)[index];
}
return val;
}
};
int main(void) {
lookup tree("root");
/* this creates the key (which is not intended) */
const char *x = tree["key"];
if (!x) printf("%s not found!\n", "key");
/* only now should the key be created */
tree["key"] = "value";
return 0;
}
答案 0 :(得分:1)
您希望tree["key"]
在const char *x = tree["key"];
中的行为与tree["key"] = "x";
中的行为不同。那是不可能的。语句中子表达式的位置对该子表达式的行为方式没有影响。
如果可以更改下标运算符的返回类型,则可能会实现与您正在寻找的行为类似的行为。如果你永远不会将缺少的值添加到树中,并返回一些对象,其行为是在赋值时添加元素(如果缺少),那么你可以使用上述两个语句来表现你喜欢的行为。
尽管如此,以上可能很难实施,可能会有一些警告。也许你不需要能够使用operator[]
查找对象而不插入miss。不要试图使用重载,而是使用单独的函数来完成它,比如保罗所建议的std::map
。