0
votes

Comment appeler une fonction d'un pointeur de fonction d'un objet instancié en C ++?

J'ai deux classes, sim code> et ielement code>. La classe ielement code> définit un pointeur de fonction, alors que la classe sim code> a un vecteur de ielement code> pointeurs. Quelle est la bonne façon d'appeler la fonction pointée à partir du pointeur de fonction définie dans ielement code>, étant donné que j'ai un vecteur de ielement * code>?

ou dans un autre mots, j'ai p> xxx pré>

et j'ai besoin d'appeler une fonction pointée à partir de ielement code>: p> xxx pré >

Je suppose que j'ai cette erreur parce que nœuds code> est un vecteur des pointeurs, et je ne suis pas au courant de la déréence nœuds [i] code> avant d'appeler sa pointe -Pour fonctionner. p>

Merci pour tout conseil. p>

Un peu plus détaillé des extraits du code sont donnés ci-dessous. p>

La méthode du SIM code> classe où je reçois l'erreur identifiant non défini code> pour la méthode de ielement code> p> xxx pré>

tandis que L'espace de noms code> éléments code>, j'ai la classe ielement code> déclaration p> xxx pré>

et la classe ielement code> Mise en œuvre P>

IElement::IElement(bool normalizeInput)
{
    if (normalizeInput)
    {
        this->SetInput= &(this->SetInput_Sum);
    }
    else
    {
        this->SetInput= &(this->SetInput_Const);
    }
}


0 commentaires

3 Réponses :


2
votes

Vous devez tous les deux obtenir la valeur de l'élément setinput de l'objet ielement à l'aide d'un opérateur de membre normal, puis appelez la fonction Membre sur le ielement < / code> objet, en utilisant -> * . En supposant que vous souhaitez utiliser le même ielement pour les deux: xxx

ou peut-être réécrire le couple de déclarations comme: xxx

Au fait, & (this-> setinput_sum) n'est pas un moyen de fonctionnement officiellement valide pour obtenir un pointeur au membre. Si votre compilateur l'accepte, cela lui permet d'extension. Le constructeur ielement doit être écrit: xxx


1 commentaires

Merci d'avoir souligné l'erreur supplémentaire ... Je n'avais pas essayé de compiler tout le code complet au moment où j'ai posté la question et que l'erreur que j'ai publiée a été signalée par Visual Studio (configuré pour compiler avec Intel Compiler)



1
votes

Cela semble aussi être un XY Problème . C ++ a des cours qui signifient que vous pouvez éviter le si en premier lieu par sous-classement et ayant une version normalisée et non normalisée de la même manière. Remplacer setInput en conséquence.

qui joue à peu près comme ceci: xxx

Les principes de conception orientés objet sont généralement orientés vers l'utilisation de classes pour faire beaucoup du travail pour vous, évitant le besoin de classes individuelles de différencier comme celle-ci.

Vous pouvez toujours capturer le booléen utilisé sur le constructeur et simplement faire référence à une propriété lors de l'exécution des opérations dont vous avez besoin, de faire en procédant dans chaque fonction ayant besoin de savoir.


4 commentaires

Un excellent point, en supposant setinput n'a pas besoin de passer à une fonction différente pendant la durée de vie d'un objet.


@aschepler exactement! Laissez la machine à faire tout le travail pour vous.


Dans le programme réel, l'IELEMENT est également une classe primitive, de sorte que de nombreuses autres classes héritent de celle-ci; Ainsi, il me semble que avoir un "code> virtuel" / code> me forcerait à déclarer deux de chaque classe dérivée également, une implémentation ielement et l'autre mise en œuvre ielementnormalized . Je ne suis pas un expert en modèles de design cependant :)


C ++ prend en charge plusieurs héritages, ce n'est donc pas toujours un gros problème. Vous pouvez également utiliser une classe de modèle où la mise en oeuvre de setinput diffère en fonction des paramètres et de passer dans une classe de normalisation à utiliser. Cela dépend de la performance sensible à ce code. Quelque chose comme ielement x et ainsi de suite.



1
votes

exemple simple de méthode d'appel via le pointeur.

#include <vector>

class IElement
{
    public:
        void action() {}
};

using MemberPtr = void (IElement::*)();    
MemberPtr Action = &IElement::action;

int main()
{
    std::vector<IElement*>  nodes{1, new IElement};

    (nodes[0]->*Action)();
    // Note the braces around the expression before the call.
    // This is because `()` binds tighter than `->*` so you need the
    // extra braces to force the `->*` to bind first so you can then call
    // the resulting method.

    //  nodes[0]->*Action();  // This will not compile.
}


1 commentaires

Peut-être que parce que j'utilise typedef à l'intérieur de la classe ielement , ceci échoue avec la même erreur dans mon cas (rapporté par Visual Studio, je n'avais pas essayé de compiler)