Когда мы должны использовать перегрузку метода против метода с другим именованием - PullRequest
8 голосов
/ 12 августа 2010

Иногда я чувствовал, что перегрузка метода может создать путаницу.

class a {
public:
    void copy(float f);
    void copy(double d);
};

a me;
me.copy(1.2); // Not obvious at the first sight on which version we are calling.

Обойти это можно.

class a {
public:
    void copyFloat(float f);
    void copyDouble(double d);
};

ОднакоИметь метод с другим именем для выполнения одинаковых функций тоже не очень хорошая идея.Могу ли я узнать, что вы считаете, чтобы выбрать среди метод перегрузки или метод с другим именованием ?

Ответы [ 6 ]

17 голосов
/ 12 августа 2010

Перегруз наверняка.

Хорошо, так что не "очевидно", какая функция вызывается (спорная) ... и что? Вам все равно, что он может принимать различные типы параметров, просто нужно делать свое дело. Если у вас разное поведение в зависимости от разных перегрузок, вы злоупотребляли перегрузками, но не указали на их недостатки.

Пример злоупотребления перегрузками:

// good:
struct has_properties
{
    void property1(float); // set property1, which happens to be a float
    void property2(int); // set property2, which happens to be an int
};

// bad:
struct has_properties
{
    void property(float); // set property1, abusing that it's a float
    void property(int); // set property2, abusing that it's an int
};

Надеюсь, вы видите проблему здесь. Если две функции имеют одинаковое имя, они должны делать одно и то же.

Еще лучше, если вы просто пытаетесь разрешить возможность работы с разными типами, просто используйте шаблон. (Возможно, это форма перегрузки.)

2 голосов
/ 12 августа 2010

Старайтесь избегать использования нескольких виртуальных методов с одинаковыми именами. Или вы, вероятно, захотите переопределить их все в производных классах. Посмотрите на следующий пример:

#include <string>

struct Base {
    virtual void foo(const std::string& arg) {
    }
    virtual void foo(int arg) {
    }
};

struct Derived : Base {
    // Only std::string version is overriden.
    virtual void foo(const std::string& arg) {
    }
};

int main() {
    Derived d;
    // This fails to compile because the name lookup stops
    // after Derived::foo has been found.
    d.foo(42); 
}
2 голосов
/ 12 августа 2010

Я бы поставил это в комментарии, но пока не могу. Поскольку вы пометили это как C ++, я подумал, что должен сказать вам, что методы обычно называются функциями в C / C ++.

1 голос
/ 12 августа 2010

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

0 голосов
/ 12 августа 2010

Перегруженные функции - это подход C ++ к группированию функций, схожих по своему поведению.

do_it (A a, B b);
do_it (B b, int i = 0);

Функции с разными именами (например, do_it_with_a или do_it_with_a_b) - это C-подход к группированию функций, схожих по своему поведению.

Так что, если ваши функции отличаются по своему поведению, не перегружайте их.

0 голосов
/ 12 августа 2010

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

...