Kapan 'fungsi statis' mulai digunakan?

25

OK, saya telah belajar apa fungsi statis itu, tetapi saya masih tidak melihat mengapa mereka lebih berguna daripada fungsi anggota pribadi. Ini mungkin semacam pertanyaan newb-ish di sini, tetapi mengapa tidak mengganti semua fungsi anggota pribadi dengan fungsi statis saja?

Dark Templar
sumber
1
Bukankah itu seharusnya "mengganti semua fungsi statis dengan fungsi anggota pribadi"? Saat ini, Anda menyatakan bahwa Anda tidak melihat titik metode statis dan terus bertanya mengapa kami tidak menggunakan lebih banyak dari mereka.
5
Apa itu "fungsi statis"? Dalam C ++, setidaknya ada dua arti (dan terakhir saya melihat draft C ++ 11, mereka telah menghapus pemberitahuan penghentian statickarena membatasi fungsi ke ruang lingkup.
David Thornley
Apakah maksud Anda "fungsi statis" dalam arti file-lingkup fungsi bebas statis di C / C ++, atau sebagai "fungsi / metode memenber statis"? Itu perbedaan besar!
Jan Hudec
@ JanHudec: Saya pikir bahwa dengan kehadiran private memberkita dapat dengan aman menganggap OP bertanya tentang konsep OO dan tidak memiliki petunjuk tentang ruang lingkup file statis.
Matthieu M.
@ MatthieuM .: Sebenarnya kehadiran 'anggota pribadi' adalah apa yang membuat saya percaya bahwa ia memang berarti fungsi statis dalam pengertian C ++. Karena fungsi statis yang tercakup file dan fungsi anggota pribadi adalah dua hal yang memiliki penggunaan yang sangat mirip dalam C ++, sementara mengganti anggota statis publik dengan anggota non-statis pribadi tidak masuk akal. Sayangnya OP sepertinya tidak merespons.
Jan Hudec

Jawaban:

25

Dengan asumsi bahwa Anda menggunakan OOP , gunakan fungsi statis ketika mereka tidak bergantung pada anggota kelas. Mereka masih bisa bersifat pribadi, tetapi dengan cara ini mereka dioptimalkan karena mereka tidak bergantung pada instance objek terkait.

Selain di atas, saya menemukan fungsi statis berguna ketika Anda tidak ingin membuat turunan objek hanya untuk menjalankan satu fungsi publik di atasnya. Ini terutama terjadi pada kelas pembantu yang berisi fungsi publik untuk melakukan pekerjaan yang berulang dan umum, tetapi tidak perlu mempertahankan keadaan apa pun di antara panggilan.

Bernard
sumber
Bernard terima kasih. Btw, apakah Anda tahu apa artinya bagi kompiler untuk "mengikat metode ke kelas"?
Dark Templar
@ Dark Templar: Tidak bisa mengatakan bahwa saya lakukan. Apakah ini khusus untuk bahasa tertentu?
Bernard
Saya punya sedikit masalah dengan definisi Anda "mereka tidak bergantung pada anggota kelas". Fungsi statis anggota tidak dapat mengakses anggota non-statis, namun mereka dapat mengakses anggota statis. Anggota statis adalah anggota kelas.
cetakan baru
@newprint: Anda benar, namun bukan itu yang saya katakan. Saya katakan ketika mereka tidak bergantung pada anggota kelas mana pun. Menggunakan anggota statis baik-baik saja jika diperlukan, tetapi itu tidak selalu terjadi.
Bernard
8

Mencoba penjelasan yang lebih sederhana daripada yang di atas (yang cukup bagus).

Objek adalah kode + data secara normal. Metode statis digunakan ketika Anda hanya memiliki bagian "kode" untuk menangani (tidak ada data / negara yang dikelola (kecuali anggota data statis)).

Brian Knoblauch
sumber
5

Karena mereka tidak memerlukan contoh dan dapat bersifat publik. Katakanlah Anda memerlukan fungsi untuk mendapatkan penyebut umum yang paling baik (GCD; sangat berguna untuk kelas pecahan; dan ya ini hanyalah contoh sederhana). Tidak ada gunanya membuat kelas objek yang tujuan utamanya adalah Anda dapat memiliki thispointer yang tidak Anda perlukan atau gunakan gcd. Jadi Anda menggunakan metode statis untuk itu, idealnya di kelas yang benar-benar menggunakan GCD (misalnya di kelas fraksi).

Tentu jika hanya ada metode statis, Anda melakukan kesalahan OOP dan harus beralih ke benar-benar melakukan OOP atau menggunakan bahasa yang lebih sesuai dengan paradigma Anda.

pengguna7043
sumber
Bukankah lebih baik dalam contoh Anda untuk menggunakan fungsi gratis?
Ela782
2
@ Ela782 Jika bahasa ini memiliki fungsi bebas, ya.
Oke, terima kasih atas jaminannya. Saya hanya mempelajari praktik terbaik ini baru-baru ini. Namun, saat ini saya sedang mengalami kesulitan melihat ketika fungsi anggota statis publik sebenarnya bisa berguna, katakanlah dalam bahasa seperti C ++. Use-case untuk keduanya adalah ketika fungsi tidak bergantung atau membutuhkan turunan dari kelas, dan kemudian, fungsi bebas adalah rekomendasi. Mungkin ini harus menjadi pertanyaan baru.
Ela782
1
@ Ela782 Ya, itu bisa membuat pertanyaan bagus. Dua poin cepat: Khususnya di C ++, anggota statis berguna untuk pemrograman meta templat karena Anda dapat meneruskan tipe sebagai parameter templat tetapi bukan namespace. Secara umum, fungsi statis dapat digunakan untuk menunjukkan bahwa fungsi tersebut sangat dekat dengan beberapa kelas, bukan hanya milik dalam namespace (think stuff::Thing::Load(...)vs stuff::LoadThing()).
2

Saya menggunakannya sebagai fungsi pembantu untuk tugas-tugas umum, contohnya adalah:

  • Mengubah derajat menjadi radian (dan sebaliknya);
  • Hashing string;
  • Konversi dari enum ke sesuatu yang lain (dalam proyek ini saya sedang bekerja, mereka bertindak sebagai tabel hash);

Sebagian besar file saya yang mengelompokkan fungsi statis memiliki Pembantu akhiran, yang berarti bahwa itulah yang mereka lakukan, membantu saya mendapatkan tempat yang lebih cepat.

George Silva
sumber
2

Seperti apa metode statis itu:

Metode statis tidak memerlukan turunan dari kelas atau mereka tidak dapat secara implisit mengakses data (atau ini, diri, Saya, dll.) Dari turunan tersebut. [ 1 ]

Contoh kapan metode statis berguna:

  • Metode global / pembantu
  • Mendapatkan hasil kueri dari kelas Model Data (memanggil SP)

Cukup gunakan di tempat yang sesuai saja.

  1. Jika Anda menemukan diri Anda menyalin metode yang sama di beberapa objek, pertimbangkan untuk membuat metode ini statis sehingga Anda dapat mengikuti KERING.
  2. Gunakan metode statis jika Anda tidak memerlukan turunan objek (Anda tidak melakukan pekerjaan dan variabel instance objek)

Jika banyak data Anda berada di luar objek dan sedang dikerjakan melalui metode statis maka kode Anda tidak berorientasi objek dan mungkin menjadi sulit untuk dipelihara.

pembuat kode
sumber
1

Statis dan privat sebenarnya ortogonal: suatu metode bisa statis, atau privat, atau tidak ada, atau keduanya.

Statis vs non-statis (alias 'metode contoh') menunjukkan apakah metode beroperasi pada kelas itu sendiri (statis) atau pada satu contoh tertentu (non-statis). Bergantung pada bahasa, Anda dapat memanggil metode statis melalui instance, tetapi Anda tidak pernah dapat mengakses instance melalui metode statis (yang juga menyiratkan bahwa Anda tidak dapat memanggil metode non-statis dari dalam metode statis, hanya karena Anda tidak memiliki thisobyek). Gunakan metode statis untuk menerapkan perilaku yang secara konsep terkait dengan kelas, tetapi tidak 'mengikat' ke satu contoh tertentu. Skenario lain di mana Anda mungkin ingin menggunakan metode statis adalah ketika Anda memiliki fungsi yang beroperasi pada dua instance kelas, dan tidak ada operan yang berhak mendapatkan status istimewa - misalnya, dengan asumsi Anda memiliki kelasVector, dan Anda ingin menerapkan penambahan; metode penambahan Anda bisa disebut sebagai a.Add(b), tetapi Vector.Add(a, b)mungkin lebih masuk akal.

Pribadi vs. publik adalah tentang visibilitas metode. Metode pribadi hanya dapat diakses dari dalam ruang lingkup kelas sendiri, sementara metode publik dapat diakses dari mana saja. Penggunaan yang paling penting untuk ini adalah enkapsulasi: dengan hanya membuat metode dan properti tersebut publik yang benar-benar dibutuhkan oleh sisa kode untuk berkomunikasi dengan kelas Anda, Anda membatasi titik di mana kode luar dapat menimbulkan masalah, dan Anda mencegah masalah di dalam kelas Anda dari pendarahan ke sisa proyek.

Jadi, aturan praktis:

  • jadikan semua fungsi anggota bersifat pribadi, kecuali yang perlu dipanggil dari luar kelas
  • membuat semua metode contoh metode, kecuali mereka masuk akal bahkan ketika tidak ada turunan kelas ada
tammmer
sumber
0

Saya menggunakan metode statis baik di C ++ dan C # untuk kelas Utility, kelas yang tidak memiliki data instan, hanya satu cara untuk menggabungkan kumpulan metode yang bermanfaat dan terkait.

int count1 = DBUtil::GetCountOfSlackerEmployees();
int count2 = DBUtil::GetCountOfEmployedSlackers();
Chris O
sumber
0

Dengan asumsi Anda berbicara tentang C ++ (Anda tidak mengatakan) dan Anda memiliki istilah yang benar (yaitu tidak berarti fungsi / metode anggota):

Bahkan fungsi anggota pribadi masih harus dideklarasikan di header, yang berarti itu benar-benar menjadi bagian dari API dan ABI kelas, meskipun pengguna tidak dapat benar-benar memanggilnya. Jika Anda menambahkan, memodifikasi, atau menghapus fungsi anggota pribadi, Anda memaksa kompilasi ulang semua kelas dependen (header telah berubah, membuat tidak bisa tahu lebih baik) dan ketika Anda melakukannya di perpustakaan, Anda harus mempertimbangkan kompatibilitas untuk aplikasi menggunakan saya t.

Di sisi lain, fungsi statis dengan cakupan file tidak mendapatkan simbol publik, sehingga Anda dapat menambah, memodifikasi, atau menghapusnya sesuka Anda dan tidak ada yang melampaui satu unit kompilasi yang akan terpengaruh.

Jan Hudec
sumber
0

Biasanya Anda memerlukan main statis untuk bertindak sebagai titik masuk untuk program Anda. Itu bisa agak penting.

Wyatt Barnett
sumber
0

Fungsi statis (dan ada arti berbeda untuk istilah itu dalam bahasa yang berbeda), tidak memerlukan status apa pun yang dipertahankan di antara panggilan. Jika secara konseptual terkait erat dengan apa yang dilakukan kelas, jadikan itu fungsi kelas (seperti pada kelas bukan objek), atau jika tidak, jadikan itu fungsi global (atau tingkat modul, apa pun). Itu tidak termasuk pada suatu objek jika tidak memerlukan keadaan objek.

Jika Anda meneruskan status ke itu sepanjang waktu, itu sebenarnya bukan fungsi stateless, Anda hanya membuat fungsi stateful dengan sintaks stateless. Dalam hal itu, itu mungkin milik objek panggilan, atau mungkin refactoring untuk lebih menyelaraskan keadaan dan perilaku ditunjukkan.

Kylben
sumber
0

"Kenapa tidak ganti semua fungsi anggota pribadi dengan fungsi statis saja?"

... karena anggota pribadi dapat mengakses data instan sementara hanya memungkinkannya terjadi dari panggilan yang dilakukan di dalam fungsi anggota lainnya. Fungsi statis bisa bersifat pribadi, tetapi tidak akan dapat mengubah atau merujuk ke turunan kelas kecuali turunan dilewatkan sebagai parameter.

jheriko
sumber
0

Lucu juga belum ada yang bisa memberikan jawaban yang bagus. Saya tidak yakin yang ini juga. Anda mungkin harus menganggapnya sebagai petunjuk bahwa mereka harus digunakan sesedikit mungkin. Mereka lebih memilih prosedural daripada OOP.

Berikut beberapa contoh lainnya:

Dalam Obj-C, di mana mereka disebut metode kelas, mereka biasanya digunakan sebagai pembungkus alokasi di mana objek dimasukkan ke dalam kolam penghitungan referensi sebelum dikembalikan.

Contoh lain dari Obj-C adalah mendaftarkan kelas baru ke koleksi kelas. Katakanlah Anda memiliki satu set kelas yang masing-masing menangani satu jenis file. Saat Anda membuat kelas baru untuk tipe file baru, Anda bisa mendaftarkannya ke koleksi (variabel global) menggunakan metode statis di kelas yang menentukan jenis file.

Dalam C + + penggunaan lain yang bisa saya pikirkan adalah untuk menangkap kesalahan dengan lembut. Fungsi konstruktor Anda tidak dapat gagal, kecuali dengan melemparkan pengecualian. Anda bisa mengatur variabel instance kesalahan, tapi itu tidak selalu tepat. Sebagai gantinya Anda dapat melakukan bagian-bagian yang mungkin gagal dalam pembungkus statis dan kemudian mengalokasikan dan mengembalikan objek baru, atau NULL pada kegagalan.

Per Johansson
sumber
0

Katakanlah Anda ingin menghitung sinus sesuatu.

Tanpa statis:

Math math = new Math()
double y = math.sin(x)

Dengan statis:

double y = Math.sin(x)

Tidak masuk akal untuk membuat sinnon-statis. Ini stateless dan hanya memproses input.

Fungsi statis tidak terikat pada objek tertentu. Mereka adalah fungsi "umum" yang independen dari keadaan internal objek.

dagnelies
sumber
Metode statis tidak "dijamin tanpa kewarganegaraan". Meskipun benar bahwa mereka tidak dapat menggunakan data contoh, mereka juga memiliki akses ke beberapa keadaan (yaitu anggota statis, kedua kelas yang dimiliki oleh metode statis dan keadaan lain yang terlihat secara global seperti variabel statis kelas lain).
@delnan: benar ... kamu benar. Biarkan saya memperbaiki ini sekarang.
dagnelies
Tanpa statis: x.sin(). Jawaban Anda mengasumsikan bahwa dosa harus menjadi fungsi "Matematika", sedangkan itu jelas berfungsi ganda.
AjahnCharles
0

Agak terlambat di sini tapi saya ingin mencoba membuat definisi yang tepat: fungsi statis adalah fungsi yang tidak atau tidak bisa mereferensikan properti instance / metode kelas yang mengandung.

Dalam beberapa bahasa, seperti C #, mungkin ada bidang atau properti statis di kelas statis, jadi tidak tepat untuk mengatakan mereka tidak digunakan untuk negara; fungsi statis mungkin menggunakan keadaan statis (global).

Pada dasarnya, intinya adalah: fungsi statis, seperti apa pun yang statis, berguna ketika masuk akal bagi mereka untuk selalu tersedia tanpa ketergantungan pada instance non-statis.

Fungsi pembantu, seperti fungsi matematika, adalah contoh yang sering ditempatkan, tetapi ada yang lain.

Jika kelas yang Anda buat mengharuskan data tidak dapat diubah, mungkin masuk akal untuk membuat fungsi statis yang mengambil instance dan memberikan instance baru karena instance tidak dapat (atau tidak seharusnya) diubah. Kelas string, misalnya, mungkin memiliki fungsi statis yang mengambil string (atau 2 atau lebih) dan meneruskan string baru.

Alasan lain mungkin karena ada kelas yang menyimpan keadaan global atau data dari beberapa jenis. Mungkin ada fungsi statis yang bekerja dengan properti atau bidang statis di kelas statis itu.

Bob
sumber
0

Saya ingin menunjukkan penggunaan lain dari f () statis.

http://www.parashift.com/c++-faq/named-ctor-idiom.html

Turun ke ini: staticfungsi memungkinkan Anda untuk membuat "Named Constructors", yaitu Anda memberi nama fungsi statis Anda dengan nama yang sesuai dan didokumentasikan sendiri, dan fungsi statis ini memanggil salah satu konstruktor (karena konstruktor memiliki nama yang identik, dan Anda dapat memiliki Banyak dari mereka, sulit untuk membedakan antara mereka).

cetakan baru
sumber