Funzione statica di sovraccarico C ++ con funzione non statica

Vorrei stampare due cose diverse a seconda che una funzione venga chiamata staticamente con Foo::print() o da un’istanza di Foo foo; foo.print(); Foo foo; foo.print();

EDIT: Ecco una definizione di class che sicuramente non funziona, come già risposto da poche persone.

 class Foo { string bla; Foo() { bla = "nonstatic"; } void print() { cout << bla << endl; } static void print() { cout << "static" << endl; } }; 

Tuttavia, c’è un buon modo per ottenere questo effetto? Fondamentalmente, mi piacerebbe fare:

 if(this is a static call) do one thing else do another thing 

Tradotto in un altro modo, so che PHP può controllare se *this variabile è definita o meno per determinare se la funzione è chiamata staticamente. C ++ ha la stessa capacità?

No, è direttamente vietato dallo standard:

ISO 14882: 2003 Standard C ++ 13.1 / 2 – Dichiarazioni sovraccaricabili

Alcune dichiarazioni di funzioni non possono essere sovraccaricate:

  • Le dichiarazioni di funzioni che differiscono solo nel tipo di reso non possono essere sovraccaricate.
  • Dichiarazioni di funzioni membro con lo stesso nome e gli stessi tipi di parametri non possono essere sovraccaricate se una di esse è una dichiarazione di una funzione membro static (9.4).

[Esempio:

 class X { static void f(); void f(); // ill-formsd void f() const; // ill-formsd void f() const volatile; // ill-formsd void g(); void g() const; // OK: no static g void g() const volatile; // OK: no static g }; 

-End esempio]

Inoltre, sarebbe comunque ambiguo dal momento che è ansible chiamare le funzioni statiche su istanze:

ISO 14882: 2003 Standard C ++ 9.4 / 2 – Membri statici

Si può fare riferimento a un membro statico di class X usando l’espressione id qualificata X::s ; non è necessario utilizzare la syntax di accesso ai membri della class (5.2.5) per fare riferimento a un static member . Si può fare riferimento a un membro static usando la syntax di accesso ai membri della class, nel qual caso viene valutata l’ object-expression . [Esempio:

 class process { public: static void reschedule(); } process& g(); void f() { process::reschedule(); // OK: no object necessary g().reschedule(); // g() is called } 

-End esempio]

Quindi ci sarebbe ambiguità con quello che hai:

 class Foo { public: string bla; Foo() { bla = "nonstatic"; } void print() { cout << bla << endl; } static void print() { cout << "static" << endl; } }; int main() { Foo f; // Call the static or non-static member function? // C++ standard 9.4/2 says that static member // functions are callable via this syntax. But // since there's also a non-static function named // "print()", it is ambiguous. f.print(); } 

Per rispondere alla domanda se è ansible verificare su quale istanza viene chiamata una funzione membro, c'è this parola chiave. this parola chiave punta all'object per cui è stata invocata la funzione. Tuttavia, this parola chiave punterà sempre a un object, ovvero non sarà mai NULL . Pertanto non è ansible verificare se una funzione viene chiamata staticamente o no alla PHP.

ISO 14882: 2003 Standard C ++ 9.3.2 / 1 - Questo puntatore

Nel corpo di una funzione membro nonstatica (9.3), la parola chiave è un'espressione non a valore lue il cui valore è l'indirizzo dell'object per cui viene chiamata la funzione.

Non è assolutamente permesso. Non vedo alcun modo pulito per raggiungere questo objective. Qual è esattamente il problema che vuoi risolvere in questo modo?

Non puoi farlo esattamente, vedi la risposta di In silico .

Ma puoi fare Foo::print() e Foo foo; print(foo); Foo foo; print(foo); fare cose diverse (Definisci void print(Foo& foo) nello stesso spazio dei nomi della class Foo , sarà trovato da ADL).

In ogni caso, questa non è una buona idea. Hai due funzioni molto simili nel nome che fanno cose completamente diverse, il che viola i buoni principi di progettazione.

La risposta è no, perché non puoi sovraccaricare in base a un tipo di ritorno.

Puoi certamente avere metodi statici in una class, ma non puoi avere:

 static void foo(); void foo(); 

Perché hanno lo stesso metodo di firma.

EDIT: ho visto il tuo commento che diceva perché volevi farlo e che volevi accedere alle variabili membro. Dovresti fare questo:

 static void print(Foo f); void print(); .... static void Foo::print(Foo f) { int a = fa; // do something with a } 

(Oppure crea getter e setter in Foo, ecc., Ma questa è l’idea generale)