Последовательность в размещении функций оператора - PullRequest
0 голосов
/ 14 июня 2010

У меня есть такой класс:

class A {
    ...private functions, variables, etc...
public:
    ...some public functions and variables...

    A operator * (double);
    A operator / (double);
    A operator * (A);
    ...and lots of other operators
}

Однако я также хочу иметь возможность делать такие вещи, как 2 * A, вместо того, чтобы иметь возможность только A * 2, и поэтому мне нужнофункции, подобные этим вне класса:

A operator * (double, A);
A operator / (double, A);
...etc...

Должен ли я поместить все эти операторы вне класса для согласованности или я должен держать половину внутри и половину снаружи?

Ответы [ 3 ]

2 голосов
/ 15 июня 2010

Из ваших ответов на комментарии в вопросе кажется, что у вас есть неявное преобразование из double в A в вашем классе. что-то вроде:

class A
{
    // ...
public:
    A(double);

    // ...
};

В этом случае вы можете просто определить свободную функцию для каждого оператора вида:

A operator*( const A&, const A& );

, и он будет использоваться, если одна из сторон является A объектом, а другая сторона неявно конвертируется в A. По этой причине часто предпочтительнее сделать симметричные бинарные операторы свободными функциями.

Зачастую проще реализовать двоичный код * с точки зрения версии присвоения *=. В этом случае я бы сделал версию присваивания функцией-членом и определил бы * как что-то вроде:

A operator*( const A& l, const A& r )
{
    A result(l);
    result += r;
    return result;
}

В противном случае, поскольку operator* является просто частью интерфейса вашего класса, у меня не возникло бы проблем с тем, чтобы сделать его friend, если требуется.

2 голосов
/ 14 июня 2010

ИМХО, проблема должна быть не в стилистической последовательности, а в последовательности инкапсуляции; как правило, если функция не нуждается в доступе к закрытым членам, она не должна быть частью класса. Это не очень быстрое правило, см. Аргументы для него здесь .

Так что, если вашим операторам не требуется частный доступ, разместите их всех снаружи. В противном случае все они должны быть внутри, вот так:

class A {
    ...
public:
    ...
    A operator * (double);
    A operator / (double);
    friend A operator * (double, A);
    friend A operator / (double, A);
    ...
};
1 голос
/ 14 июня 2010

Итак, вы говорите, что, поскольку вы должны поместить некоторые операторы (те, у которых A не является первым параметром) вне класса, возможно, вы должны поместить их всех туда, чтобы люди знали, где их найти ? Я так не думаю. Я ожидаю найти операторы внутри класса, если это вообще возможно. Конечно, поместите «внешние» в один файл, это поможет. И если внешним требуется доступ к закрытым переменным-членам, то добавление строк friend является огромным указанием для поиска в других местах файла этих операторов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...