2010-10-14 3 views
0

Pouvez-vous me donner un exemple quand je ne peux pas passer argument par référence et que j'ai besoin d'utiliser un pointeur. J'ai trouvé un exemple, mais je ne suis pas sûr. Supposons que vous ayez une classe D dérivée de la classe de base Bquand j'ai besoin de passer par le pointeur (et non par référence)

Vous devez pointer si vous voulez faire:

void function(B* b){...} 
int main{ 
    D* d; 
    function(d); 
} 
+1

Vous pourriez utiliser une référence dans votre exemple. – JoshD

+1

J'ai posé la question équivalente tout récemment http://stackoverflow.com/questions/3835741/are-reference-and-pointer-equal-with-regards-to-polymorphism – pm100

Répondre

6

La seule fois où vous ne pouvez pas utiliser une référence et vous devez utiliser un pointeur est si vous permettez le concept de « aucun argument » en passant un pointeur NULL. Toutefois, vous pouvez utiliser des pointeurs comme arguments lorsque vous stockez réellement un pointeur sur ce qui a été passé. La plupart des développeurs C++ remarqueront que vous n'utilisez pas de référence et accorderont une attention particulière à ce que dit votre documentation.

+0

On pourrait argumenter que vous n'avez même pas * besoin * un pointeur, si vous écrivez un objet qui a un état nullable. Mais quoi que –

+0

Oui, mais tous les objets ne sont pas valables, surtout quand vous utilisez RAII :-) –

+0

@John Dibling: Je ne suis pas ce fan du concept Nullable (au moins intégré), je préfère de loin le 'boost :: optionnel 'hook, afin de distinguer par type ce qui peut et ne peut pas être nul. –

-1

la seule raison est si vous devez passer null. Si vous voulez appeler la fonction en disant 'Je n'en ai pas un'

6

S'il existe une directive de codage (comme celle de Google) qui dit d'utiliser des arguments de pointeur, alors c'est ce que vous faites.

Sinon, seule déclarer votre propre fonction avec pointeur argument formel lorsque

  • un nullpointer est un argument réel significatif & valide ou

  • l'argument réel est le pointeur le plus naturellement déjà, ou

  • vous allez stocker ce pointeur quelque part.

cas Peut-être plus, mais je pense que vous obtenez la dérive: quand vous avez un choix (pas de ligne directrice de codage dire autrement), préfèrent les références.

Vive & HTH,

+0

+1 pour "l'argument actuel est déjà le plus naturellement". Un exemple évident est qu'une fois que vous parlez d'itération, votre souci est autant de savoir où vous êtes dans la séquence que quel objet dans la séquence que vous regardez. Par exemple. http://stackoverflow.com/questions/3909784/how-do-i-find-a-particular-value-in-an-array-and-return-its-index/3909788#3909788. – Brian

+3

Bien sûr, n'utilisez pas Google. C'est stupide. – GManNickG

0

Si vous souhaitez autoriser l'absence d'un objet, vous devez utiliser des pointeurs.

// This allows DoSomething to receive pointers to NULL, which cannot 
// be done with references 
void DoSomething(Something *pSomething) 
{ 
    if (pSomething) 
    { 
    ... 
    } 
} 

int main() 
{ 
    Something *pSomething=NULL; 

    DoSomething(pSomething); 
} 
+1

au lieu d'une fonction-long 'if', considérons' if (! PSomething) {return; } 'en haut :) –

+0

@Matthieu: Mais alors la fonction aurait plus d'une sortie! ....: P – GManNickG

-2

Je pense que si vous voulez passer une fonction, vous devez la passer par un pointeur. Je ne vois pas comment vous pouvez passer la fonction par référence.

Par exemple, prenez la fonction suivante:

#include <iostream> 
#include "math.h" 

void myfun (double value, size_t nofloops, double (*function)(double)) 
    { 
    std::cout << value << std::endl; 
    for (size_t i=0;i<nofloops;++i) 
     { 
     value = function(value); 
     std::cout << value << std::endl; 
     } 
    std::cout << "------------------" << std::endl; 
    } 

void main() 
    { 
    myfun(100,10,sin); 
    myfun(100,10,cos); 
    myfun(100,10,sqrt); 
    } 

La fonction dans ce petit utilitaire exécute la fonction donnée un certain nombre de fois, en prenant le résultat comme entrée dans la prochaine itération. Je ne vois pas comment vous pouvez passer la fonction par référence.

+1

-1 pour 'void main', qui est invalide en C et C++ (et n'a jamais été valide dans les deux langues) .Re passant par référence: remplace simplement' (* function) 'par' (& fonction) '. C'est tout. :-) Cheers & hth., –

+0

PS: Lorsque vous passez une fonction par référence, vous obtenez une bête très étrange (c'est probablement pourquoi vous pensiez que cela ne pouvait pas être fait), une * lecture seule référence *. Ce n'est pas une référence à const, mais vous ne pouvez pas l'assigner. Parce que vous ne pouvez pas assigner à une fonction, et quand vous pensez à une référence comme juste un alias, un autre nom, alors cela a du sens. –

+0

Apparemment, certains anciens compilateurs C autorisent "void main". Voir http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/legality-of-void-main.html. – Patrick

1

Un autre cas: si la chose vous passez est le dernier argument avant varargs:

void fn1(A &a, ...); // Uh oh 
void fn2(A *a, ...); // Good 

Je ne sais pas si cela est requis par la norme, ou est juste un bug dans la mise en œuvre de le compilateur C++ que j'utilise.

+0

La norme dit seulement que les arguments variables doivent être le dernier argument, ou peut-être qu'il doit y avoir un argument précédent. Le type de cet argument n'est définitivement pas mentionné. – Puppy

+0

Un type POD juste avant '...' n'est pas requis pour déclarer ou définir une fonction, mais il est nécessaire de récupérer ces arguments utilement en utilisant 'va_start()'. 18.7p3: "Si le paramètre [de' va_start'] est déclaré avec une fonction, un tableau ou un type de référence, ou avec un type qui n'est pas compatible avec le type résultant de la transmission d'un argument pour lequel il n'y a pas de paramètre, le comportement est indéfini. " – aschepler

+0

Aussi, dans cette situation, je recommande de créer une conversion implicite de 'classe A' à une structure POD qui contient un pointeur' A * ', et en utilisant cela comme dernier argument nommé, afin que les utilisateurs puissent appeler la fonction comme si le premier type d'argument était vraiment 'A' (ou référence associée). – aschepler

1

En règle générale, vous utilisez des pointeurs pour l'une des deux choses:

  • Reassignability - vous ne pouvez pas rebind une référence .
  • Pointeurs nulles - il n'y a pas de chose comme référence nulle.

Si votre cas d'utilisation prévu ne nécessite aucune de ces deux propriétés, utilisez une référence. Sinon, utilisez un pointeur.

Questions connexes