6
votes

C ++ Obtenir le type de classe intérieur Fonction statique

à l'intérieur d'une fonction de membre statique, j'ai besoin d'obtenir le type.

#define RPC_FUNCTION(funcName) \
static void rpc_##funcName(void* oOwner, RpcManager::RpcParamsContainer params){ ((__class__*)oOwner)->funcName(params); }; \
void funcName(RpcManager::RpcParamsContainer params);


0 commentaires

6 Réponses :


-2
votes

Non, une méthode statique ne peut voir que des membres statiques de la classe. Il n'a pas de sens pour qu'il accède aux membres de l'instance (comme dans les variables standard, etc.) car ils n'existent que si la classe n'a été instanciée.

On dirait que vous voulez quelque chose comme le singleton modèle de conception. Cela permet uniquement à une seule instance de la classe d'exister à la fois.

Une autre façon serait d'avoir une liste statique de toutes les instances d'une classe, puis dans le constructeur de classe, ajoutez le pointeur sur cette liste. Comme je le disais cependant, les membres statiques ne peuvent pas accéder aux variables d'instance, car elles n'existent peut-être pas du tout.

Je suppose que la question est une plus grande question: pourquoi avez-vous besoin d'accéder à une variable d'instance d'un membre statique? Si vous avez besoin d'accéder à un membre d'instance, vous devez appeler la fonction dans le contexte de l'instance actuelle, sinon vous brisez le paradigme de l'OOP assez dur.


7 commentaires

Désolé j'aurais dû être plus clair. Je n'essaie pas d'accéder à des variables d'instance. Tout ce que je veux, c'est le type myClass sans l'écrire explicitement.


Oh, désolé, vous souhaitez donc instancier une instance de la classe que le membre statique appartient?


Fondamentalement oui - mais je ne peux pas simplement écrire myClass * foo = nouvelle myClass;


Malheureusement, je ne pense pas qu'il y ait un moyen. Vous pourriez prendre le nom de la classe comme paramètre à la macro.


Oui, c'est ce que je vais faire, je pense. J'ai essentiellement tout cela pour éviter d'avoir un deuxième paramètre à une macro. Merci de votre aide.


Il suffit de regarder autour de vous, voyez si votre compilateur prend en charge la classe __ macro, et cela fait ce que vous attendez. Je pense que c'est spécifique de GCC.


@Deadmg - J'ai supposé en premier lieu, il souhaitait accéder à un membre d'instance d'une méthode statique, auquel cas un singleton fonctionnerait, mais ne soyez pas la meilleure solution, c'est donc demander pourquoi cela était nécessaire. Il s'avère que j'ai interprété la question de la question cependant, alors oui, un singleton n'est pas le moyen de faire le tour de cela.



1
votes

Je crois que ce que vous demandez au cœur n'est tout simplement pas possible: C ++ est un langue statiquement dactylographiée , ce qui signifie que toutes les informations de type doivent être disponibles au moment de la compilation (polymorphisme d'exécution nonobstant) . C'est-à-dire que lorsque vous dites, xxx

puis le type t doit être connu être connu au moment de la compilation. " t_from_user () x; ", dans lequel le type type d'une variable est déterminé au moment de l'exécution. La langue n'est tout simplement pas conçue de cette façon.

Habituellement si vous posez une telle question qui est un indicateur que vous allez dans le mauvais sens, cependant. Les solutions typiques des situations polymorphes impliquent des fonctions de classe et des fonctions virtuelles, ou d'autres types de tables de recherche, ou vraiment un nombre quelconque d'approches différentes. Votre demande de macro de préprocesseur indique également que quelque chose est désactivé. Tout langage de programmation a ses idiomes et qui se font trop loin de ceux-ci est généralement une mauvaise idée.


6 commentaires

En quelque sorte, je l'utilise plus pour casser un objet (c'est actuellement un vide *) à l'intérieur d'une macro. Comme ceci: statique vide molfunction (void * propriétaire) {// J'ai besoin d'obtenir myClass afin que je puisse la jeter sans l'écrire explicitement. (MyClass *) propriétaire-> myMemberfunction (); }


Pourquoi ne postez-vous pas votre problème réel dans la question et nous pouvons jeter un coup d'oeil? Le plus résumé le mieux; Supposons toujours que toutes les décisions que vous avez déjà apportées à la résolution du problème ont peut-être partie dans la mauvaise direction.


@cleversoap: vous pouvez simplement faire doter vos classes avec un typef Typedef myclass Seltype; et toujours mettre Reterpret_cast (propriétaire) dans votre macro.


Pourquoi reterpret_cast ? Un simple static_cast suffira.


Ce typdef semble être la meilleure solution. Je viens d'appeler une macro init dans des déclarations de classe. Merci pour votre aide!


@Xeo: En effet, merci! static_cast (propriétaire) Il devrait être ... CLEVERSOAP: Ne pas litière macros partout si vous pouvez obtenir le même effet avec essentiellement la même quantité d'écriture de code C ++ approprié. Macros est eevil: -s



0
votes

Ce que vous voulez faire est appelé réflexion. Il a été mis en œuvre dans .NET (je ne sais pas, peut-être aussi en Java) et sera mis en œuvre dans les normes futures de C ++.


1 commentaires

Je crois que le problème est typing statique , pas manque de réflexion. La réflexion est quelque chose de légèrement différent.



0
votes

Il semble que vous disposiez de quelques classes non liées qui ont un certain nombre de méthodes communes (celles qui peuvent être envoyées sous la forme de l'argument code> funcname code> dans votre exemple).

au lieu de les avoir non liés classes, envisagez une approche polymorphe. Par exemple, disons que les fonctions que vous prenez en charge sont Func1 CODE> et FUNC2 CODE>, vous pourrez y travailler de la sorte: P>

#define RPC_FUNCTION(funcName) static void rpc_##funcName(BaseClass* oOwner, RpcManager::RpcParamsContainer params){ oOwner->funcName(params); };


2 commentaires

Très probablement, ces fonctions statiques fonctionneront comme des rappels, et le paramètre Void * ne peut pas être modifié. Néanmoins, la même approche pourrait être utilisée, je viens de lancer le pointeur vide sur basoclass * à l'intérieur de la fonction. Cependant, cela entraînera un coût d'exécution, ce qui n'est pas nécessaire, car ce que les désirs de l'OP peuvent facilement être obtenus de manière statique.


@Xeo: Bien sûr, mais à mon avis, il s'agit d'une conception plus propre avec un code plus maintenu. La performance n'est pas la seule métrique à utiliser lors de la mise en œuvre de la solution.



0
votes

recherche la macro de la fonction? C'est une macro qui se développe au nom de la fonction actuelle.

 __FUNCTION__


0 commentaires

3
votes

Dans Visual Studio 2012, vous pouvez utiliser ce truc, mais cela ne fonctionnera pas dans GCC, au moins pour l'instant.

        template<typename base_t>
        static auto GetFunctionBaseType(void(base_t::*)())->base_t;

        struct TBase
        {
            template<typename T> void GetBaseType();
            typedef decltype(GetFunctionBaseType(&GetBaseType<void>)) this_t;

            static void rpc_func1(void * ptr)
            {
                ((this_t*)ptr)->func1();
            }
        };


0 commentaires