Saya sedang mengerjakan proyek C ++ di mana saya memiliki banyak fungsi matematika yang awalnya saya tulis untuk digunakan sebagai bagian dari kelas. Karena saya telah menulis lebih banyak kode, saya menyadari saya membutuhkan fungsi matematika ini di mana-mana.
Di mana tempat terbaik untuk meletakkannya? Katakanlah saya punya ini:
class A{
public:
int math_function1(int);
...
}
Dan ketika saya menulis kelas lain, saya tidak bisa (atau setidaknya saya tidak tahu bagaimana) menggunakannya math_function1
di kelas lain. Plus, saya menyadari beberapa fungsi ini tidak benar-benar terkait dengan kelas A. Mereka tampaknya berada di awal, tetapi sekarang saya bisa melihat bagaimana mereka hanya fungsi matematika.
Apa praktik yang baik dalam situasi ini? Saat ini saya telah menyalin-menempelkan mereka ke kelas-kelas baru, yang saya yakin adalah praktik terburuk.
static
kata kunci?Jawaban:
C ++ dapat memiliki fungsi non-metode dengan baik, jika mereka bukan milik kelas tidak menempatkan mereka di kelas, hanya menempatkan mereka di lingkup namespace global atau lainnya
sumber
math_function1(42)
mungkin memanggil anggota kelas saat ini;special_math_functions::math_function1(42)
jelas memanggil fungsi independen). Yang sedang berkata,::math_function(42)
memberikan disambiguasi yang sama.// optional
. Bumbui sesuai selera.Tergantung pada bagaimana proyek diatur dan apa pola desain yang Anda gunakan, dengan asumsi ini adalah kode utilitas Anda memiliki pilihan berikut:
Perhatikan bahwa opsi pertama akan menjadi taruhan terbaik dan ketiganya adalah kegunaan terbatas. Walaupun begitu, Anda mungkin akan bertemu hanya karena C # atau programmer Java melakukan beberapa pekerjaan C ++ atau jika Anda pernah bekerja pada C # atau kode Java di mana penggunaan kelas adalah wajib.
sumber
Seperti yang sudah Anda katakan, copy-paste kode adalah bentuk terburuk dari penggunaan kembali kode. Jika Anda memiliki fungsi yang bukan milik kelas Anda atau dapat digunakan untuk beberapa skenario, tempat terbaik untuk meletakkannya adalah kelas pembantu atau kelas utilitas. Jika mereka tidak menggunakan data instance apa pun, mereka bisa dibuat statis, jadi Anda tidak perlu membuat instance dari kelas utilitas untuk menggunakannya.
Lihat di sini untuk diskusi tentang fungsi anggota statis dalam C ++ asli dan di sini untuk kelas statis dalam C ++ terkelola. Anda kemudian dapat menggunakan kelas utilitas ini di mana pun Anda akan menempelkan kode Anda.
Dalam .NET misalnya, hal-hal seperti
Min()
danMax()
disediakan sebagai anggota statis diSystem.Math
kelas .Jika semua fungsi Anda berhubungan dengan matematika dan Anda ingin orang lain memiliki
Math
kelas raksasa , Anda mungkin ingin memecahnya lebih lanjut dan memiliki kelas sepertiTrigonometryUtilities
,EucledianGeometryUtilities
dan sebagainya.Pilihan lain adalah menempatkan fungsionalitas bersama ke kelas dasar dari kelas-kelas yang membutuhkan fungsionalitas tersebut. Ini bekerja dengan baik, ketika fungsi-fungsi dalam pertanyaan perlu beroperasi pada data instan, namun, pendekatan ini juga kurang fleksibel jika Anda ingin menghindari pewarisan berganda dan hanya menempel pada satu kelas dasar, karena Anda akan "menggunakan" basis satu Anda kelas hanya untuk mendapatkan akses ke beberapa fungsi bersama.
sumber
Tidak jelas istilah "Fungsi pembantu". Satu definisi adalah fungsi kenyamanan yang Anda gunakan sepanjang waktu hanya untuk menyelesaikan pekerjaan. Mereka dapat hidup di namespace utama dan memiliki header sendiri, dll. Definisi fungsi helper lainnya adalah fungsi utilitas untuk satu kelas atau keluarga kelas.
Sekarang
isPrinter
tersedia untuk semua kode termasuk tajuknya, tetapiprint_alignment_page
memerlukanusing namespace printer_utils::Xerox;
arahan. Orang juga dapat merujuknya sebagaiagar lebih jelas.
C ++ STL memiliki
std::
namespace yang mencakup hampir semua kelas dan fungsinya, tetapi memecahnya secara kategorikal menjadi lebih dari 17 header yang berbeda untuk memungkinkan pembuat kode mendapatkan nama kelas, nama fungsi, dll. Jika mereka ingin menulis mereka sendiri.Bahkan, TIDAK dianjurkan untuk menggunakan
using namespace std;
file header atau, seperti yang sering dilakukan, sebagai baris pertama di dalammain()
.std::
adalah 5 huruf dan sering tampaknya menjadi tugas untuk mengawali fungsi yang ingin digunakan (terutamastd::cout
danstd::endl
!) tetapi memang memiliki tujuan.C ++ 11 baru memiliki beberapa sub-namespaces di dalamnya untuk layanan khusus seperti
yang bisa dibawa untuk digunakan.
Teknik yang bermanfaat adalah komposisi namespace . Satu mendefinisikan ruang nama kustom untuk menahan ruang nama yang Anda butuhkan untuk
.cpp
file khusus Anda dan menggunakannya sebagai ganti sekelompokusing
pernyataan untuk setiap hal dalam ruang nama yang mungkin Anda butuhkan.Teknik ini membatasi pemaparan pada keseluruhan
std:: namespace
( ini besar! ) Dan memungkinkan seseorang untuk menulis kode pembersih untuk baris kode paling umum yang paling sering ditulis orang.sumber
Anda mungkin ingin meletakkannya di fungsi templat untuk membuatnya tersedia untuk berbagai jenis bilangan bulat dan / atau mengapung:
Anda dapat juga membuat jenis kustom yang rapi yang mewakili misalnya angka besar atau angka kompleks dengan membebani operator yang relevan untuk jenis kustom Anda untuk membuatnya ramah terhadap template.
sumber