C++ surcharge statique fonction avec non-statique fonction
Je voudrais imprimer deux choses différentes selon qu'une fonction est appelée statiquement avec Foo::print()
ou à partir d'une instance de Foo foo; foo.print();
EDIT: Voici une définition de classe qui ne fonctionne certainement pas, comme répondu par quelques personnes déjà.
class Foo {
string bla;
Foo() { bla = "nonstatic"; }
void print() { cout << bla << endl; }
static void print() { cout << "static" << endl; }
};
Cependant, est-il un bon moyen d'obtenir cet effet? Fondamentalement, je voudrais faire:
if(this is a static call)
do one thing
else
do another thing
Formulé d'une autre manière, je sais que PHP peut vérifier si la variable *this
est définie ou non pour déterminer si la fonction est appelé statiquement. Est-ce que C++ a la même capacité?
4 réponses
Non, il est directement interdit par la norme:
ISO 14882: 2003 norme C ++ 13.1 / 2-déclarations Superposables
Certaines déclarations de fonction ne peuvent pas être surchargé:
- les déclarations de fonction qui ne diffèrent que par le type de retour ne peuvent pas être surchargées.
- les déclarations de fonctions membres portant le même nom et les mêmes types de paramètres ne peuvent pas être surchargées si l'un d'entre eux est une déclaration de fonction membre
static
(9.4)....
[Exemple:
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
};
-exemple de fin]
...
D'ailleurs, ce serait ambigu de toute façon puisqu'il est possible d'appeler des fonctions statiques sur les instances:
ISO 14882: 2003 norme C++ 9.4 / 2-membres statiques
Un membre statique
s
de la classeX
peut être référencé à l'aide du qualified-id expressionX::s
; ce n'est pas nécessaire pour utiliser la syntaxe d'accès des membres de classe (5.2.5) pour désigner unstatic member
. Unstatic
Membre peut être référé à l'aide la syntaxe d'accès des membres de la classe, dans quel cas leobject-expression
est évaluer. [Exemple:
class process {
public:
static void reschedule();
}
process& g();
void f()
{
process::reschedule(); // OK: no object necessary
g().reschedule(); // g() is called
}
-exemple de fin]
...
Il y aurait donc une ambiguïté avec ce que vous avez:
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();
}
Pour répondre à votre question de savoir si vous pouvez vérifier quelle instance une fonction membre est en cours appelé, il y a le mot clé this
. Le mot clé this
pointe vers l'objet pour lequel la fonction a été invoquée. Cependant, le mot clé this
pointera toujours vers un objet, c'est-à-dire qu'il ne sera jamais NULL
. Par conséquent, il n'est pas possible de vérifier si une fonction est appelée statiquement ou non à la PHP.
ISO 14882: 2003 C++ Standard 9.3.2 / 1-ce pointeur
Dans le corps d'un non statique (9.3) fonction membre, le mot-clé
this
est un non lvalue expression dont la valeur est l'adresse de l'objet pour lequel la fonction est appelée.
Ce n'est certainement pas autorisé. Je ne vois aucun moyen propre d'y parvenir. Quel est exactement le problème que vous voulez résoudre de cette façon?
Vous ne pouvez pas faire cela exactement, voir dans la réponse de silico .
, Mais vous pouvez faire Foo::print()
et Foo foo; print(foo);
faire des choses différentes. (Définissez void print(Foo& foo)
dans le même espace de noms que class Foo
, il sera trouvé par ADL).
En tout cas, ce n'est pas une bonne idée. Vous avez deux fonctions très similaires dans le nom qui font des choses complètement différentes, ce qui viole les bons principes de conception.
La réponse est non, car vous ne pouvez pas surcharger en fonction d'un type de retour.
Vous pouvez certainement avoir des méthodes statiques dans une classe, mais vous ne pouvez pas avoir:
static void foo();
void foo();
Parce Qu'ils ont la même signature de méthode.
EDIT: j'ai vu votre commentaire disant pourquoi vous avez voulu faire cela, et que vous vouliez accéder aux variables membres. Vous devez faire ceci:
static void print(Foo f);
void print();
....
static void Foo::print(Foo f)
{
int a = f.a;
// do something with a
}
(ou créer des getters et des setters dans Foo, etc, mais c'est l'idée générale)