Apakah ide yang baik untuk memberikan tanda tangan fungsi berbeda yang melakukan hal yang sama?

23

Berikut adalah kelas C ++ yang dibangun dengan tiga nilai.

class Foo{

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

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

Semua tipe parameter berbeda.
Saya bisa membebani konstruktor sehingga pesanan tidak masalah.

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

Tapi apakah itu ide yang bagus?
Saya mulai melakukannya karena saya tahu hal-hal apa yang dibutuhkan kelas / fungsi;
Saya tidak selalu ingat bagaimana urutannya.


Saya telah mengasumsikan bahwa kompiler mengoptimalkan ini seolah-olah saya memanggil konstruktor yang sama.

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

Apa pendapat Anda tentang kelebihan fungsi sehingga pesanan tidak menjadi masalah?


Juga, Jika saya menulis beberapa fungsi utilitas,
apakah ide yang baik untuk memberikan nama fungsi berbeda yang melakukan hal yang sama?

misalnya.

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

Saya tidak sering melihat keduanya tetapi konvensi serupa.
Haruskah saya menghentikan atau memeluk kebiasaan itu?

Trevor Hickey
sumber
1
Seseorang seharusnya hanya mengeluarkan upaya menyediakan berbagai cara untuk mengekspresikan sesuatu jika masing-masing cara yang disediakan secara eksplisit dalam beberapa kasus akan jelas dan jelas lebih unggul daripada yang lain. Itu tidak berarti seseorang harus secara umum mengeluarkan upaya untuk memastikan bahwa sesuatu hanya dapat ditulis dalam satu bentuk kanonik, tetapi tidak masuk akal untuk melakukan upaya yang memungkinkan sesuatu untuk ditentukan dengan cara yang bukan yang terbaik.
supercat
Semacam duplikat dari pertanyaan saya di sini (sekarang saya setuju bahwa itu adalah ide yang buruk).
leftaroundabout

Jawaban:

93

Saya bisa membebani konstruktor sehingga urutan [dari parameter] tidak masalah ... Tapi apakah itu ide yang bagus?

Tidak.

Memiliki kelebihan konstruktor yang berbeda akan memiliki efek sebaliknya dari apa yang Anda inginkan. Programer yang datang setelah Anda mengharapkan kelebihan beban yang berbeda untuk memiliki perilaku yang berbeda, dan akan bertanya: "Apa jenis perilaku berbeda yang diungkapkan oleh masing-masing kelebihan ini?

Sebagian besar programmer mengharapkan disiplin memiliki parameter metode dalam urutan yang telah ditentukan, dan alat seperti IntelliSense akan memberi tahu mereka urutan parameter yang diharapkan saat mereka memasukkannya.


Memiliki beberapa nama fungsi yang melakukan hal yang sama adalah masalah yang sama; programmer mengharapkan varian memiliki perilaku yang berbeda. Tolong, satu fungsi atau metode per perilaku, dan hanya mengadopsi pola penamaan yang konsisten.

Robert Harvey
sumber
14
banyak suara. Saya akan segera berhenti. Terima kasih.
Trevor Hickey
8
Selain itu, Anda tidak dapat memberi nama konstruktor secara berbeda untuk menjelaskan tujuan Anda, pembaca harus menyimpulkannya dari parameter. Kelebihan konstruktor dengan cara ini membuat lebih sulit untuk dipahami.
Zachary Yates
3
"Memiliki beberapa nama fungsi yang melakukan hal yang sama ..." - untuk waktu yang 'menyenangkan', lihat kelas-kelas Ruby String Hash Array File .
+1. Anda berhadapan dengan pengembang / programmer. Gagasan Microsoft tentang "pengguna adalah monyet", tidak berfungsi di sini.
Manoj R
1
@ZacharyYates Kurangnya "nama konstruktor" dapat diselesaikan dengan mengekspos metode konstruksi statis sebagai gantinya. Ini adalah praktik standar di Jawa, meskipun tidak begitu banyak di C ++.
Xion
14

Kadang-kadang mendukung pergantian di antara argumen diperlukan. Contohnya:

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

Kami tidak ingin multiplikasi dari intdan doubleuntuk menghitung sesuatu yang berbeda jika operan dibalik. Kami juga tidak ingin memaksa programmer untuk mengingat bahwa ketika mengalikan ints dan doubles, thedouble terjadi di sebelah kiri!

Tidak masalah bahwa ini adalah operator karena hal yang sama berlaku untuk:

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

Itu benar-benar tergantung pada jenis fungsinya. Sementara sebagian besar programmer mungkin menginginkan dukungan untuk komutatif di perpustakaan aritmatika, mereka tidak selalu menginginkan, katakanlah, fungsi perpustakaan I / O untuk mendukung semua perintah argumen yang mungkin.

Kekhawatiran mungkin bergantung pada persarangan yang diharapkan di mana pemanggilan fungsi akan terlibat. Fleksibilitas dalam operator aritmatika memungkinkan kita untuk mengubah struktur keseluruhan dari sintaksis pohon untuk memperjelas ekspresi keseluruhan: kelompok bersama-sama istilah yang serupa dan semacamnya.

Kaz
sumber