operator [] =重载?

问题描述 投票:6回答:8

好吧,我正在尝试将一个快速的小类作为一种哈希表来工作。如果我可以让它工作,那么我应该能够这样做:

  StringHash* hash = new StringHash;
  hash["test"] = "This is a test";
  printf(hash["test"]);

它应该打印出“这是一个测试”。

看起来我现在有2个问题。首先我这样做了:

const char* operator[](const char* key) {
  for(int i = 0; i < hashSize; ++i) {
    if(strcmp(hkeys[i], key) == 0) {return values[i];}
  }
  return NULL;
}

但是当我尝试查找值时,编译器会抱怨这一点

错误:数组下标的类型`StringHash * [const char [5]]'无效

其次operator [] =在这里似乎不是正确的语法。我能找到的唯一另一件事是&operator []但是我不认为这会起作用,因为我必须编写查找程序??? (这个语法不仅仅用于返回数组项引用吗?)

我想在这里做什么甚至可能吗?任何建议表示赞赏:)


似乎对我正在尝试做的事情感到困惑。我会发布我的代码:

http://pastebin.com/5Na1Xvaz


所有帮助后的成品:

http://pastebin.com/gx4gnYy8

c++ operator-overloading brackets
8个回答
2
投票

我会首先质疑为什么在编写自己的HashMap时有一些版本可用,尽管不是标准版本。

你的hash-map是否存储const char * pointers或std :: strings? (它可能存储const char *指针,如果它只是一个查找表,存储在别处的数据,不会改变它的生命周期)。

当找不到项目时,operator []应该做什么?

现在让我假设答案是: - 是的,我们存储const char *指针,并且我们在空单元格中存储NULL - 当我们执行hash [key] = value时,我们想要将键与值相关联 - 如果我们只是这样做hash [key]但不写,它不插入

这可以使用魔术对象完成:当您为此对象分配const char *时,它会插入或覆盖散列。您还可以从对象隐式转换为const char *以进行读取。

这是非常复杂的,并且最好坚持map的常规接口:operator []总是插入并且您使用不同的方法来查找。


6
投票

错误是因为hash是一个指针。改成:

StringHash hash;

4
投票

其他答案与您的第一个问题有关。至于你的第二个......

如果你返回一个引用,那么你将返回一个左值。您始终可以分配左值。

是的,它(几乎)真的很简单。不过,我建议你仔细阅读是否需要const

我记得读到的是你应该为const提供const和非operator[]重载,如下所示:

MyType const &operator[](int index) const; // This is the array access version (no assignment allowed), which should work on const objects
MyType &operator[](int index);      // This is the array access or assignment version, which is necessarily non-const.

有关更多信息,请参阅此链接。


3
投票

hash不是StringHash对象。它指向一个指针。

你可以这样做:

(*hash)["test"] = "This is a test";

或者你可以问问自己为什么你需要一个指向它的指针,

StringHash hash;
hash["test" = "This is a test";

...或者即使你这样做,为什么你不会使用像auto_ptr这样的智能指针。

#include <memory>
std::auto_ptr<StringHash> hash( new StringHash );
(*hash)["test"] = "This is a test";

2
投票

第一个错误是您声明哈希是一个指针。指针类型已经可以与索引运算符一起使用。例如,指针[3]相当于*(指针+ 3)。你无法改变这种行为。使哈希成为对象本身:

StringHash sh;

至于operator [] =,没有这样的东西。您的索引运算符应该只返回一个引用,以使赋值工作。以下是一个简单的示例:

class Indexable
{
   std::string arr[3];
public:
   std::string & operator[](int index) {
      return arr[index];
   }
   std::string const& operator[](int index) const {
      return arr[index];
   }
};

2
投票

五个问题:

  1. hash是指向StringHash的指针,你必须取消引用它才能使用运算符:(*hash)["test"]
  2. 如果要分配给元素,则必须返回对元素类型的引用 const char *& operator[] (const char* key); // ... (*hash)["test"] = "This is a test"; // will compile now
  3. null不是C ++中的关键字。使用0或NULL
  4. 如果没有找到,operator []必须为元素分配空间。返回NULL不是一种选择。否则,尝试分配(*hash)["test"]的结果将导致程序崩溃。
  5. 使用std :: map或std :: tr1 :: unordered_map而不是编写自己的“快速”类。

而且只是成为一个混蛋:你知道这不是哈希表,对吗?


2
投票

StringHash hash;而不是new的东西。 C ++不是Java。 :-)


1
投票

你能用boost::unordered_map<std::string, std::string吗?那么你不必担心自己实现这个。

假设它是你自己的某种练习:你可能来自不同的背景,但在C ++中,声明你的哈希的常规方法是:

StringHash hash;

此外,您的operator[]可能适用于打印,但它不适用于作业。通常,operator[]方法通过返回非const引用或可以为其分配新值的代理对象来工作,而您的方法也不会。如果您能够使用std :: string,则可以重写您的方法以返回非const引用,以指向应该读取或分配的哈希中的位置。

© www.soinside.com 2019 - 2024. All rights reserved.