Чи гарна ідея надати різні підписи функцій, які роблять те саме?


23

Ось клас C ++, який будується з трьома значеннями.

class Foo{

    //Constructor
    Foo(std::string, int, char);

private:
    std::string foo;
    char bar;
    int baz;
};

Усі типи параметрів різні.
Я міг би перевантажити конструктор, щоб порядок не мав значення.

class Foo{

    //Constructors
    Foo(std::string, char, int);
    Foo(std::string, int, char);
    Foo(char, int, std::string);
    Foo(char, std::string, int);
    Foo(int, std::string, char);
    Foo(int, char, std::string);


private:
    std::string foo;
    char bar;
    int baz;
};

Але це гарна ідея?
Я почав це робити, бо знав, які речі потрібні класу / функції;
Я не завжди пам’ятав, в якому порядку їх приймав.


Я припускав, що компілятор оптимізує це так, ніби я назвав той же конструктор.

//compiler will implement this with the same code? 
//maybe not.. I could call a function to get a parameter, 
//and that function could change the state of the program, before calling
//a function to get another parameter and the compiler would have to
//implement both
Foo foo1("hello",1,'a');
Foo foo2('z',0,"world");

Яка ваша думка щодо перевантаження функції, щоб порядок не мав значення?


Крім того, якщо я пишу деякі функції утиліти,
чи добре б надати різні імена функцій, які роблять те саме?

напр.

void Do_Foo();
void DoFoo();
void do_foo();
//etc..

Я часто не бачу цих двох, але подібних умов.
Чи слід порушувати або вживати звичку?


1
Слід лише витратити зусилля, забезпечуючи кілька способів виразити щось, якщо кожен явно наданий спосіб буде в явних випадках однозначно і однозначно перевершує будь-який з інших. Це зовсім не означає, що варто витрачати зусилля на забезпечення того, щоб щось можна було написати лише в одній канонічній формі, але не має сенсу докладати зусиль, що дозволяють щось конкретизувати якось не найкращим чином.
supercat

Якийсь дублікат мого запитання тут (я згоден, що це погана ідея).
близько

Відповіді:


93

Я міг би перевантажити конструктор, щоб порядок [параметрів] не мав значення ... Але це гарна ідея?

Ні.

Наявлення різних перевантажень конструктора матиме протилежний ефект від того, що ви маєте намір. Програміст, що приходить після того, як ви очікуєте, що різні перевантаження мають різну поведінку, і запитає: "Яку різну поведінку виражає кожна з цих перевантажень?

Більшість програмістів очікує дисциплінованості встановлення параметрів методу у заздалегідь визначеному порядку, а такі інструменти, як IntelliSense, підкажуть їм очікуваний порядок параметрів під час їх введення.


Наявність декількох імен функцій, які роблять одне і те ж, - одна і та ж проблема; програмісти очікують, що варіанти мають різну поведінку. Будь ласка, одну функцію чи метод за поведінкою, і просто прийняти послідовну схему іменування.


14
багато голосів. Я негайно зупинюсь. Дякую тобі.
Тревор Хікі

8
Крім того, ви не можете по-різному назвати конструктори, щоб пояснити своє призначення, читачі повинні зробити висновок про його параметри. Перевантаження конструктора таким чином набагато важче зрозуміти.
Захарій Йейтс

3
"З декількома іменами функцій, які роблять те саме ..." - "на хороший" час, перегляньте Файли масиву String Hash Array у класах Рубі .

+1. Ви маєте справу з розробниками / програмістами. Ідея Microsoft "користувач - мавпа", тут не працює.
Маной Р

1
@ZacharyYates Нестачу "імен конструктора" можна подолати, викривши натомість статичні методи побудови. Це стандартна практика на Java, хоча не стільки в C ++.
Сіон

14

Іноді необхідна підтримка комутації серед аргументів. Наприклад:

double operator *(int, double);
double operator *(double, int);

Ми не хочемо множення а intта doubleобчислити щось інше, якщо операнди будуть перевернуті. Ми також не хочемо змушувати програмістів пам’ятати, що при множенні ints та doubles, doubleліворуч йде!

Не має значення, що це оператор, оскільки те саме стосується:

footype plus(const footype &, const bartype &);
footype plus(const bartype &, const footype &);

Це дійсно залежить від видів функції. Хоча більшість програмістів, ймовірно, хочуть підтримувати комутативність в арифметичних бібліотеках, вони не обов'язково хочуть, скажімо, функцій бібліотеки вводу / виводу для підтримки всіх можливих порядків аргументів.

Занепокоєння, ймовірно, залежить від очікуваного гніздування, в якому будуть задіяні виклики функцій. Гнучкість в арифметичних операторах дозволяє нам змінити загальну структуру дерева синтаксису для уточнення загального виразу: згрупуйте разом подібні терміни та ін.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.