Invocarea unei metode de clasă c++ fără o instanță de clasă? (Programare, C++)

utilizator58925 a intrebat.

Este posibil să se invoce o metodă c++ o metodă de clasă fără a crea mai întâi o instanță de clasă?

Să presupunem că avem următorul cod:

// just an example 
#include <iostream>
using namespace std;

class MyClass {
    public:
        MyClass();
        ~MyClass();
        int MyMethod(int *a, int *b);
};

// just a dummy method
int MyClass::MyMethod(int *a, int *b){;
    return a[0] - b[0];
}

Iată un alt exemplu:

#include <iostream>
using namespace std;

class MyClassAnother {
    public:
        MyClassAnother();
        ~MyClassAnother();
        int MyMethod(int *a, int *b);
};

// just a dummy method
int MyClassAnother::MyMethod(int *a, int *b){;
    return a[0] + b[0];
}

După cum putem observa, în exemplele de mai sus, ambele clase nu au variabile interne și folosesc constructori / destructori fictivi; Singurul lor scop este de a expune o metodă publică, MyMethod(..). Iată întrebarea mea: să presupunem că există 100 de astfel de clase în fișier (toate cu nume de clase diferite, dar cu o structură identică – o metodă publică având același prototip – . MyMethod(..).

Există o modalitate de a invoca metoda MyMethod(..) metode ale fiecăreia dintre clase fără a crea mai întâi o instanță de clasă pentru fiecare dintre ele?

Comentarii

  • Ce-ar fi să faceți MyMethod static? functionx.com/cppcli/classes/Lesson12b.htm –  > Por rjz.
  • Și chiar aveți nevoie de constructor/destructor? Hei, de ce nu folosiți o funcție liberă de la bun început? –  > Por Keith.
  • @Keith – Nu am nevoie de constructor/destructor. Dar am nevoie ca toate metodele să se numească MyFunction() — așa că, pentru a diferenția între diferitele metode, le înfășor în clase diferite; Ai o idee mai bună despre cum să obțin această funcționalitate și în același timp să le numesc pe toate. MyFunction()? –  > Por user58925.
  • @rjz — mulțumesc. Aceasta pare să fie calea. Acum, doar pentru a fi sigur, dacă ambele clase au o altă metodă, Helper(...), și că Helper(...) se numește din interiorul ambele MyMethod(...) metode, fiecare MyMethod(...) va invoca metoda sa propriul Helper(...) adică, va invoca metoda Helper(...) care aparține aceleiași clase, corect? –  > Por user58925.
  • @rjz — mulțumesc pentru ajutor! –  > Por user58925.
3 răspunsuri
Greyson

Folosiți cuvântul cheie „static” pentru a declara metoda:

static int MyMethod( int * a, int * b );

Apoi puteți apela metoda fără o instanță, astfel:

int one = 1;
int two = 2;

MyClass::MyMethod( &two, &one );

Metodele ‘static’ sunt funcții care folosesc doar clasa ca spațiu de nume și nu necesită o instanță.

Comentarii

  • @Greyson – vă mulțumesc! Deci, în principiu, mergând pe metoda static ruta, voi putea defini 100 de clase + MyMethod() metode și să le invoc fără instanțe de clasă, nu? MyClass1::MyMethod( &two, &one ); MyClass2::MyMethod( &two, &one ); …………… MyClass3::MyMethod( &two, &one ); Am înțeles bine? –  > Por user58925.
  • Corect. Dacă aceasta va fi o clasă utilitară, sugerez să faceți constructorul private astfel încât să nu existe nicio greșeală că această clasă nu este menită să fie instanțiată. –  > Por Greyson.
  • @Greyson — da, chiar nu am nevoie nici de constructor, nici de destructor aici; Cu toate acestea, intenționez să am 1000 de astfel de clase incluse într-un fișier utilitar – este aceasta o practică bună? există o modalitate mai bună de a realiza acest lucru, putând în același timp să numesc toate aceste metode. MyMethod(...)? –  > Por user58925.
  • Pentru a judeca dacă a avea sute de clase cu o singură metodă statică este o bună practică, aș avea nevoie de un context mai larg. Ce încercați să realizați prin utilizarea aceluiași nume de metodă? –  > Por Greyson.
  • În primul rând, cred că voi ajunge să am mii, sau chiar zeci de mii; În al doilea rând, principalul motiv este să nu trebuiască să inițializez o instanță de clasă de fiecare dată când vreau să invoc o metodă MyMethod(...) apel; Acest lucru va fi folosit într-o aplicație sensibilă la timp care va folosi 10000 de astfel de metode – m-am gândit că ar fi o pierdere dacă ar trebui să instanțiez o clasă înainte de fiecare apel de acest tip. Ce părere aveți? Voi avea probleme de memorie? –  > Por user58925.
Mark Ransom

Puteți apela o metodă de clasă fără o instanță prin declararea acesteia static, dar nu pare să fie ceea ce doriți. Doriți să puteți apela aceeași metodă pe 100 de clase diferite.

Există două moduri în care C++ poate face diferența între metodele diferitelor clase. Una este să o facă la compilare, iar cealaltă este să o facă la execuție. La compilare trebuie să apelați numele clasei în sine ca parte a apelului unei metode statice sau trebuie ca instanța obiectului sau pointerul să fie la o clasă derivată specifică. În momentul execuției, puteți apela o metodă în mod polimorf dacă ați declarat metoda ca fiind virtuală. Rețineți că aveți nevoie de un obiect al clasei pentru a utiliza oricare dintre metodele în timp de execuție.

Comentarii

  • Da, vreau să apelez aceeași numele metodeiMyMethod(). Cu toate acestea, fiecare clasă va avea o implementare diferită pentru MyMethod(). Va fi declarată static mă va ajuta să apelez la diversele MyMethod() metode, invocând de fiecare dată o clasă / implementare diferită? –  > Por utilizator58925.
  • @user58925, nu, declarând-o. static va face imposibilă utilizarea polimorfică a metodei. Trebuie să o declarați virtual, dar apoi trebuie să o apelați și de la o instanță a clasei. Nu există nicio cale de ocolire. –  > Por Mark Ransom.
  • Nu sunt sigur că mă clarific în mod corespunzător; în principiu, în mod ideal aș dori să definesc MyMethod() metode ca funcții libere (fără clase); Cu toate acestea, acest lucru mă va obliga să dau fiecăreia dintre aceste funcții un nume diferit și, prin urmare, pentru a simplifica procesul, mi se pare logic să folosesc pur și simplu același nume (MyFunction), în timp ce fiecare dintre acestea este înfășurată într-o clasă unică; Cum este virtual va fi de ajutor în cazul ilustrat mai sus? mulțumesc! –  > Por utilizator58925.
  • @user58925, efectiv fiecare funcție statică primește un nume diferit deoarece trebuie să le prefixați cu numele clasei. MyClass1::MyMethod este diferită de MyClass2::MyMethod. Când este virtuală, puteți folosi un obiect pentru a le diferenția, iar codul de apelare nu trebuie să știe ce metodă va fi apelată. myArray[0] = new MyClass1; myArray[1] = new MyClass2; myArray[0]->MyMethod(a, b); myArray[1]->MyMethod(a, b); –  > Por Mark Ransom.
  • Vă mulțumim, Mark. Care ar fi avantajul de a defini metodele ca fiind virtuale Vs. abordarea sugerată de @dasblinkenlight de mai jos (care utilizează doar static pentru a defini metoda)? Mulțumesc pentru tot ajutorul dumneavoastră! –  > Por utilizator58925.
stanigator

După cum au menționat Mark Random și Greyson, puteți face acea metodă statică și apoi puteți invoca semnătura corectă fără a instanția un obiect. Cu toate acestea, este posibil să doriți să vă gândiți de două ori înainte de a scrie funcția dvs. în acest mod, mai degrabă decât să scrieți o versiune diferită a aceleiași funcții. Iată care sunt considerentele, în special pentru un program mare:

  • metodele statice sunt dificil de scris teste unitare pentru.
  • D/din cauza naturii metodelor statice, acestea rezidă în memorie tot timpul.
  • Multithreading-ul ar fi dificil dacă programul dvs. trebuie să îl utilizeze.

Comentarii

  • Vă mulțumesc. Adevărul este că voi avea 1000 de astfel de clase într-un fișier utilitar și va trebui să apelez la toate MyMethod(...) metode la un moment dat sau altul; chiar nu vreau să fiu nevoit să creez o instanță de fiecare dată înainte de a apela o clasă. MyMethod(...) — prin urmare, m-am gândit că static este calea de urmat. Aveți o sugestie mai bună / alternativă la aceasta? –  > Por utilizator58925.
  • vreo idee despre cât de multă memorie (aproximativ) fiecare dintre MyMethod(...) poate lua? Va fi o problemă de memorie dacă voi avea 1000 de astfel de metode în memorie? –  > Por user58925.
  • Ce este greu în a scrie un test pentru o metodă statică? Este cam același lucru ca și pentru o funcție liberă. Este greu dacă presupui că trebuie să faci o subclasă pentru a testa, dar aceasta nu este abordarea corectă pentru o metodă care împărtășește invarianta de stare a clasei. –  > Por mabraham.

Tags: