È una buona idea fornire firme di funzioni diverse che facciano la stessa cosa?


23

Ecco una classe C ++ che viene costruita con tre valori.

class Foo{

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

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

Tutti i tipi di parametri sono diversi.
Potrei sovraccaricare il costruttore in modo che l'ordine non abbia importanza.

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

Ma è una buona idea?
Ho iniziato a farlo perché sapevo quali cose avevano bisogno di una classe / funzione;
Non ricordavo sempre in che ordine li prendesse.


Presumo che il compilatore lo ottimizzi come se avessi chiamato lo stesso costruttore.

//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");

Quali sono le tue opinioni sul sovraccarico di una funzione in modo che l'ordine non abbia importanza?


Inoltre, se sto scrivendo alcune funzioni di utilità,
è una buona idea fornire nomi di funzioni diverse che facciano la stessa cosa?

per esempio.

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

Non vedo spesso queste due ma convenzioni simili.
Dovrei rompere o abbracciare l'abitudine?


1
Uno dovrebbe spendere sforzi fornendo molteplici modi di esprimere qualcosa se ogni modo esplicitamente fornito in alcuni casi sarà chiaramente e inequivocabilmente superiore a uno degli altri. Ciò non significa che uno dovrebbe generalmente spendere sforzi per garantire che qualcosa possa essere scritto solo in una forma canonica, ma non ha senso fare sforzi permettendo che qualcosa venga specificato in un modo che non è il migliore.
supercat

Una specie di duplicato della mia domanda qui (ora sono d'accordo sul fatto che sia una cattiva idea).
circa il

Risposte:


93

Potrei sovraccaricare il costruttore in modo che l'ordine [dei parametri] non abbia importanza ... Ma è una buona idea?

No.

Avere sovraccarichi di costruttori diversi avrà l'effetto opposto di ciò che si intende. Il programmatore che viene dopo di te si aspetta che diversi sovraccarichi abbiano un comportamento diverso e chiederà: "Che tipo di comportamento diverso viene espresso da ciascuno di questi sovraccarichi?

La maggior parte dei programmatori si aspetta la disciplina di avere i parametri del metodo in un ordine predefinito e strumenti come IntelliSense diranno loro l'ordine previsto dei parametri quando li inseriscono.


Avere più nomi di funzioni che fanno la stessa cosa è lo stesso problema; i programmatori si aspettano che le varianti abbiano comportamenti diversi. Una funzione o metodo per comportamento, per favore, e basta adottare un modello di denominazione coerente.


14
molti voti positivi. Mi fermerò immediatamente. grazie.
Trevor Hickey,

8
Inoltre, non puoi nominare i costruttori in modo diverso per spiegare il tuo scopo, i lettori devono dedurlo dai parametri. Il sovraccarico del costruttore in questo modo rende molto più difficile la comprensione.
Zachary Yates,

3
"Avere più nomi di funzioni che fanno la stessa cosa ..." - per un tempo "buono", guarda le classi di Ruby String Hash Array File .

+1. Hai a che fare con sviluppatori / programmatori. L'idea di Microsoft "utente è scimmia" non funziona qui.
Manoj R,

1
@ZacharyYates La mancanza di "nomi di costruttori" può essere risolta esponendo invece metodi di costruzione statici. Questa è una pratica standard in Java, anche se non tanto in C ++.
Xion,

14

A volte è necessario sostenere la commutazione tra argomenti. Per esempio:

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

Non vogliamo moltiplicare un inte doublecalcolare qualcosa di diverso se gli operandi sono invertiti. Né vogliamo costringere i programmatori a ricordare che quando si moltiplicano ints e doubles, il doubleverso va a sinistra!

Non importa che si tratti di un operatore perché lo stesso vale per:

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

Dipende davvero dal tipo di funzione. Mentre la maggior parte dei programmatori probabilmente desidera il supporto per la commutatività nelle librerie aritmetiche, non vuole necessariamente, diciamo, una funzione di libreria I / O per supportare tutti i possibili ordini di argomenti.

La preoccupazione probabilmente dipende dal nidificazione prevista in cui saranno coinvolte le chiamate di funzione. La flessibilità negli operatori aritmetici ci consente di modificare la struttura generale dell'albero di sintassi per chiarire l'espressione generale: raggruppare termini simili e tali.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.