Перегрузка нескольких операторов - PullRequest
6 голосов
/ 02 октября 2011

Вкратце, моя цель - чтобы foo [bar] возвращал type1, а foo [bar] = возвращал type2.

Я пишу объект на C ++, и он продвигается довольно хорошо, однако я хочу сделать только одну крошечную вещь, но это кажется невозможным.

Мой объект - это класс хранения, поэтому я использую индекс массива для доступа к значениям. Мне также нужно назначить, поэтому я также перегружаю оператор =. Однако это несколько неудобно, потому что значения, которые содержит мой класс, являются объектами первого класса, поэтому при перегрузке нижнего индекса моего массива я не могу вернуть их как есть. Я должен вернуть промежуточный класс для обработки оператора =, но я также хочу получить значение без дополнительной типизации.

Есть ли способ сделать это? Хакерские способы приемлемы.

Редактировать: Вот пример того, что он (должен) делать

#include<cstdio>
#include<cstdlib>

class foo{
    char* a[100];
    foo(){
        for( int i = 0; i < 100; i ++)
            a[i] = 0;
    }
    char* operator[] (int location){
        return a[location];
    }
    foo& operator[]= (int location, const char* value ){
        if( a[location] == 0 )
            a[location] = (char*) malloc( strlen( value ) + 1 );
        else
            a[location] = (char*) realloc( a[location], strlen( value ) + 1 );
        strcpy( a[location], value );
    }
};
int main(){
    foo bar;
    bar[20] = "Hello";
    printf( "bar[20] = %s\n", bar[20] );
    bar[20] = "Hello There";
    printf( "bar[20] = %s\n", bar[20] );
    printf( "bar[20][0] = %c\n", bar[20][0] );
}

Output:
bar[20] = Hello
bar[20] = Hello There
bar[20][0] = H

Отредактируйте снова: я думаю, что я попытаюсь сформулировать это другим, но выполнимым способом. Есть ли способ перегрузить возвращаемый тип при ссылке на класс? Такой, что если у меня

class foo{
    bool a;
    bool operator /*referenced*/ (){
        return a
    }
    foo& operator=(bool b){
        a = b;
    }
};
int main(){
    foo a;
    a = b;
    if( a == b )
        printf("It Works!");
}

что на самом деле будет работать?

Ответы [ 2 ]

5 голосов
/ 02 октября 2011

Нет operator[]=, поэтому решение состоит в том, чтобы написать некоторый класс-оболочку с двумя ключевыми функциями: operator=, который принимает значение и устанавливает его в родительский контейнер, и оператор неявного преобразования, который принимает значение из родительского контейнера и возвращает его. Ваш operator[] вернет такую ​​упаковку.

class foo
{
    friend class wrapper;
public:
    class wrapper
    {
        friend class foo;
        foo & _parent;
        int _index;

        wrapper(foo & parent, int index) : _index(index), _parent(parent) {}
    public:  
        wrapper & operator=(const char * value)
        {
            if( _parent.a[_index] == 0 )
                _parent.a[_index] = (char*) malloc( strlen( value ) + 1 );
            else
                _parent.a[_index] = (char*) realloc( _parent.a[_index], strlen( value ) + 1 );
            strcpy( _parent.a[_index], value );

            return *this;
        }

        operator char *()
        {
            return _parent.a[_index];
        }
    };

    char* a[100];
    foo()
    {
        for( int i = 0; i < 100; i ++)
            a[i] = 0;
    }
    wrapper operator[] (int location){
        return wrapper(*this, location);
    }
};

Что касается второго вопроса, вы всегда можете перегрузить operator== на foo. Но, может быть, я неправильно понял.

0 голосов
/ 02 октября 2011

Если вы готовы использовать C ++ (как подсказывает ваш тег), то большая часть работы была проделана за вас:

class foo: public vector<string>
{
public:
  foo()
  {
    resize(100);
  }
};

int main()
{
   foo bar;

   bar[20] = "Hello";
   cout << "bar[20] = " << bar[20] << endl;
   bar[20] = "Hello There";
   cout << "bar[20] = " << bar[20] << endl;
   cout << "bar[20][0] = " << bar[20][0] << endl;
}
...