开发者

Overloading [] operator in C++

Im trying to overload the [] operator in c++ so that I can assign / get values from my data structure like a dictionary is used in c#:

Array["myString"] = etc.

Is this possible in c++?

I attempted to overload the operator but it doesnt seem to work,

Record& MyDictionary::operator[] (string& _Key)
{
for (int i = 0; i < used;开发者_开发问答 ++i)
{
    if (Records[i].Key == _Key)
    {
        return Records[i]; 
    }
}
 }

Thanks.


Your code is on the right track - you've got the right function signature - but your logic is a bit flawed. In particular, suppose that you go through this loop without finding the key you're looking for:

for (int i = 0; i < used; ++i)
{
    if (Records[i].Key == _Key)
    {
        return Records[i]; 
    }
}

If this happens, your function doesn't return a value, which leads to undefined behavior. Since it's returning a reference, this is probably going to cause a nasty crash the second that you try using the reference.

To fix this, you'll need to add some behavior to ensure that you don't fall off of the end of the function. One option would be to add the key to the table, then to return a reference to that new table entry. This is the behavior of the STL std::map class's operator[] function. Another would be to throw an exception saying that the key wasn't there, which does have the drawback of being a bit counterintuitive.

On a totally unrelated note, I should point out that technically speaking, you should not name the parameter to this function _Key. The C++ standard says that any identifier name that starts with two underscores (i.e. __myFunction), or a single underscore followed by a capital letter (as in your _Key example) is reserved by the implementation for whatever purposes they might deem necessary. They could #define the identifier to something nonsensical, or have it map to some compiler intrinsic. This could potentially cause your program to stop compiling if you move from one platform to another. To fix this, either make the K lower-case (_key), or remove the underscore entirely (Key).

Hope this helps!


On a related note, one of the problems with operator[](const Key& key) is that, as templatetypedef states, in order to return a reference it needs to be non-const.

To have a const accessor, you need a method that can return a fail case value. In STL this is done through using find() and the use of iterators and having end() indicate a fail.

An alternative is to return a pointer, with a null indicating a fail. This is probably justified where the default constructed Record is meaningless. This can be also be done with the array operator:

Record* MyDictionary::operator[] (const string& keyToFind) const
{ 

    for (int i = 0; i < used; ++i)
    {
        if (Records[i].Key == keyToFind)
        {
            return &Records[i]; 
        }
    }
    return 0;
}

There is certainly a view that operator[] should return a reference. In that case, you'd most likely implement find() as well and implement operator[] in terms of it.

To implement find() you need to define an iterator type. The convenient type will depend in implementation. For example, if Records[] is a plain old array:

typedef Record* iterator;
typedef const Record* const_iterator;
const_iterator MyDictionary::end()const
{
    return Records + used;
}
const_iterator MyDictionary::begin() const
{
    return Records;
}
const_iterator MyDictionary::find(const string& keyToFind) const
{ 
    for (iterator it = begin(); it != end(); ++it)
    {
        if (it->Key == keyToFind)
        {
            return it; 
        }
    }
    return end();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜