Когда должен мы использовать перегрузку метода по сравнению с методом с другим именованием

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

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);
};

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

8
задан GManNickG 12 August 2010 в 03:47
поделиться

6 ответов

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

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

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

// 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
};

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

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

17
ответ дан 5 December 2019 в 07:33
поделиться

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

#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
ответ дан 5 December 2019 в 07:33
поделиться

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

1
ответ дан 5 December 2019 в 07:33
поделиться

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

2
ответ дан 5 December 2019 в 07:33
поделиться

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

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

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

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

0
ответ дан 5 December 2019 в 07:33
поделиться

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

0
ответ дан 5 December 2019 в 07:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: