С++ перегрузка постфиксного/префиксного оператора как функция, не являющаяся членом

Я пишу свой собственный класс массива в качестве упражнения. Поскольку я читал, что функции, не являющиеся членами, на самом деле в некоторых отношениях лучше, чем функции-члены. (Скотт Мейерс)

Я пытаюсь написать как можно больше перегрузок операторов как функций, не являющихся членами. Оператор перегружает + , - все отлично работает как функции, не являющиеся членами.

my_array operator+(const my_array & left, const my_array & right);
my_array operator-(const my_array & operand);
my_array & operator++();  // prefix
my_array   operator++(int); //postfix, compiler puts a 0

Однако операторы префикса/постфикса как функции, не являющиеся членами, вызывают проблемы (они отлично работают, если я использую разрешение области и делаю их функциями-членами)

Я понимаю, что не каждая перегрузка оператора может быть функцией-членом. Но у меня возникают проблемы с тем, почему эти две функции не могут быть функциями, не являющимися членами. Ошибка, которую я получаю:

: 'my_array& operator++()' must have an argument of class or enumerated type

Что в основном может быть решено, если я сделаю их функциями-членами и позволю передать * этот массив obj в следующем формате.

(*this).operator++();

Но все дело в том, что я не хочу делать их функциями-членами в первую очередь! Итак, операторы pre/post fix не могут/не должны быть реализованы как функция, не являющаяся членом?

Я пришел к выводу, что, поскольку постфикс/префикс является унарным оператором, у них есть только один аргумент (обычно это *this). Итак, если я хочу, чтобы компилятор неявно предоставлял указатель *this и вызывал перегрузки, они должны быть реализованы как функция-член.

Мои рассуждения верны? Если нет, как мне реализовать это как функцию, не являющуюся членом? Спасибо, что предоставили мне некоторое представление.


comment
Что делают ваши операторы ++? Вызов ++ для каждого элемента?   -  person Adam Burry    schedule 13.09.2013
comment
‹br›yap, это просто упражнение в написании кода. ‹br/› ‹pre› my_array& operator++( my_array & operand) //prefix { for (int i = 0; i ‹ operand.get_number_of_elements(); ++i) { ++(операнд[i]); } вернуть операнд; } my_array operator++(my_array &operand, int) // postfix { my_array result(operand); ++(операнд); вернуть результат; }   -  person thassan    schedule 13.09.2013


Ответы (1)


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

#include <iostream>

struct my_array
{
    // your members here.
};

my_array& operator ++(my_array& obj)
{
    // access to members is through obj.member
    std::cout << "++obj called." << std::endl;
    return obj;
}

my_array operator ++(my_array& obj, int)
{
    my_array prev = obj;

    // modify obj, but return the previous state.        
    std::cout << "obj++ called." << std::endl;

    return prev;
}

int main(int argc, char *argv[])
{
    my_array obj;
    ++obj;
    obj++;
    return 0;
}

Вывод

++obj called.
obj++ called.
person WhozCraig    schedule 13.09.2013
comment
это делает это .. У меня были проблемы с тем, как в этом случае будет работать постфиксная подпись. my_array& operator ++(my_array& obj, int) отвечает на мой вопрос. Некоторые из моих рассуждений были неверны - person thassan; 13.09.2013
comment
@thassan На самом деле постфикс, указанный в ответе, не обычный. Он должен возвращаться по значению, потому что он должен возвращать значение до приращения. - person Angew is no longer proud of SO; 13.09.2013
comment
@Angew, я согласен. Это был список параметров, который он искал, но я соответствующим образом обновлю ответ. Спасибо за орлиный взгляд. - person WhozCraig; 13.09.2013
comment
@WhozCraig На самом деле, я заметил это в очереди на проверку, когда кто-то отредактировал это, но они изменили его на const my_array, который мне пришлось отклонить как недействительный. Мы не хотим возвращать значение const теперь, когда существует семантика перемещения. - person Angew is no longer proud of SO; 13.09.2013
comment
@Angew Без шуток. Я был в очереди на проверку? Ах. чье-то редактирование было в очереди. Очень ценю, что вы принесли его сюда. У меня нет проблем с исправлением того, что не так, чтобы быть уверенным. (здесь еще слишком рано, еще не хватает кофеина =P). - person WhozCraig; 13.09.2013
comment
@Angew, мы не хотим возвращать значение const теперь, когда существует семантика перемещения. Правда? Конечно, возвращаемое значение постфиксного оператора является временным, и вы не хотите, чтобы оно случайно изменялось. - person Adam Burry; 13.09.2013
comment
@AdamBurry Но вы определенно хотите иметь возможность уйти от этого. И даже если вы мутируете его по-другому, что с того? - person Angew is no longer proud of SO; 13.09.2013
comment
@Angew, ах, теперь я вижу жалобу. Вы должны иметь возможность перемещаться из объекта const. Ты можешь не? Я думал, что const означает потокобезопасность, а не побитовую неизменяемость. - person Adam Burry; 13.09.2013
comment
@AdamBurry Это означает, что вы не можете его изменить. Операция перемещения ctor/перемещения должна принимать const my_array&& в качестве параметра, и вы мало что можете сделать с помощью константной ссылки. Вы, конечно, не можете назначать элементы данных (например, украсть указатель и установить его в nullptr). - person Angew is no longer proud of SO; 13.09.2013
comment
@Angew Спасибо за редактирование, кстати. проклятая проверка орфографии на моем Mac становится немного навязчивой, когда я пишу код на SO = P. - person WhozCraig; 13.09.2013
comment
@Angew, см.: herbsutter.com/ 01/01/2013/video-you-dont-know-const-and-mutable и обсуждение здесь: stackoverflow.com/questions/14100660/ - person Adam Burry; 13.09.2013
comment
@AdamBurry Я видел выступление Саттера. Но у языка есть свои правила — вы не можете изменить объект через const значение gl, за исключением mutable членов объекта типа класса. - person Angew is no longer proud of SO; 13.09.2013
comment
Этот момент обсуждается здесь: stackoverflow.com/questions/7138780/ - person Adam Burry; 13.09.2013