Função Estática de Sobrecarga C ++ com Função Não Estática

Eu gostaria de imprimir duas coisas diferentes, dependendo se uma function é chamada estaticamente com Foo::print() ou de uma instância de Foo foo; foo.print(); Foo foo; foo.print();

EDIT: Aqui está uma definição de class que definitivamente não funciona, como já foi respondido por algumas pessoas.

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

No entanto, existe uma boa maneira de conseguir esse efeito? Basicamente, gostaria de fazer:

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

Phrased de outra maneira, eu sei que o PHP pode verificar se a variável *this está definida ou não para determinar se a function é chamada estaticamente. O C ++ possui o mesmo recurso?

Não, é diretamente proibido pela norma:

Norma C ++ ISO 14882: 2003 13.1 / 2 – Declarações passíveis de sobrecarga

Certas declarações de function não podem ser sobrecarregadas:

  • Declarações de function que diferem apenas no tipo de retorno não podem ser sobrecarregadas.
  • Declarações de function de membro com o mesmo nome e os mesmos tipos de parâmetro não podem ser sobrecarregados se algum deles for uma declaração de function de membro static (9.4).

[Exemplo:

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

– por exemplo

Além disso, seria ambíguo, uma vez que é possível chamar funções estáticas em instâncias:

Norma C ++ ISO 14882: 2003 9.4 / 2 – Membros estáticos

Um membro estático da class X pode ser referido usando a expressão id-qualificada X::s ; não é necessário usar a syntax de access do membro da class (5.2.5) para se referir a um static member . Um membro static pode ser referido usando a syntax de access de membro de class, nesse caso a object-expression é avaliada. [Exemplo:

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

– por exemplo

Então, haveria ambiguidade com o que você tem:

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

Para resolver sua dúvida sobre se você pode verificar em qual instância uma function de membro está sendo chamada, existe a palavra this chave this . A palavra this chave this aponta para o object para o qual a function foi chamada. No entanto, a palavra this chave this sempre apontará para um object, ou seja, nunca será NULL . Portanto, não é possível verificar se uma function está sendo chamada estaticamente ou não como PHP.

ISO 14882: 2003 C ++ Standard 9.3.2 / 1 - O ponteiro deste

No corpo de uma function de membro nonstatic (9.3), a palavra this chave this é uma expressão não-lvalue cujo valor é o endereço do object para o qual a function é chamada.

Definitivamente não é permitido. Eu não vejo nenhuma maneira limpa de conseguir isso. Qual é exatamente o problema que você quer resolver dessa maneira?

Você não pode fazer isso exatamente, veja a resposta de In silico .

Mas você pode fazer Foo::print() e Foo foo; print(foo); Foo foo; print(foo); faça coisas diferentes. (Defina void print(Foo& foo) no mesmo namespace da class Foo , ele será encontrado pelo ADL).

De qualquer forma, isso não é uma boa ideia. Você tem duas funções muito semelhantes no nome que fazem coisas completamente diferentes, o que viola os bons princípios de design.

A resposta é não, porque você não pode sobrecarregar com base em um tipo de retorno.

Você certamente pode ter methods estáticos em uma class, mas não pode ter:

 static void foo(); void foo(); 

Porque eles têm a mesma assinatura de método.

EDIT: Eu vi o seu comentário dizendo por que você queria fazer isso, e que você queria acessar variables ​​de membro. Você precisaria fazer isso:

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

(Ou crie getters e setters em Foo, etc, mas essa é a ideia geral)