Est-ce une bonne pratique de passer l'objet en tant que paramètre struct à une fonction en c ++?

StackOverflow https://stackoverflow.com/questions/2724708

  •  02-10-2019
  •  | 
  •  

Question

J'ai essayé un exemple en direct ci-dessous:

typedef struct point
{
    int x;
    int y;
} point;

void cp(point p)
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
}

Le résultat des thats est imprimé sur:

1
2

qui est ce que je pensais. Ma question est: Est-ce que le paramètre p obtenir la copie intégrale de l'objet p1? Si oui, je me demande si cela est une bonne pratique? (Je suppose quand le struct obtient de grande taille, cela va créer beaucoup de frais généraux de copie).

Était-ce utile?

La solution

Il n'y a rien de mal avec le passage de struct en tant que paramètres. Tout est passé par valeur en C ++ donc une copie complète est en effet fait.

La struct que vous avez donné dans votre exemple est petit il est donc probablement pas un problème si vous passez par valeur. Mais si vous travaillez avec de plus grandes structures de données, vous pouvez passer par référence.

Attention cependant, en passant par des moyens de référence que si vous modifiez la struct dans votre fonction, votre sera modifiée struct originale. Assurez-vous d'utiliser le mot-clé const dans tous les cas où vous ne modifiez pas le struct. Cela vous donnera une information immédiate sur les si vos fonctions ne modifient les informations ou non.

Votre exemple pourrait être modifié pour travailler avec les références de cette façon:

typedef struct point
{
    int x;
    int y;
} point;

void cp(const point& p) // You can know that cp doesn't modify your struct
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

void mod_point(point& p) // You can know that mod_points modifies your struct
{
    p.x += 1;
    p.y += 1;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
    mod_point(p1);
    cp(p1); // will output 2 and 3
}

Autres conseils

Oui, il n'y a rien de mal à ce et oui, p est une copie complète de p1. Je ne dirais pas un struct avec deux ints grande, mais si le struct ne se grand et si vous n'avez pas besoin de le modifier dans le corps de la fonction vous pourriez envisager de passer par référence const:

void cp(const point& p)
{
    // ...
}

Avant de donner une réponse à votre question (vous le trouverez à la fin de ce post), voici un bref résumé des possibilités que vous avez pour passer des arguments à une fonction:


1. copier des objets construits (passage par valeur):

void cp(point p);

Ceci est passe par valeur. Un objet point temporaire est créé et construit copie de tout objet point vous passez dans cp. Une fois que les feuilles d'exécution de la fonction de cp, l'objet temporaire est détruit.

Notez que parce que la fonction fonctionne sur une copie de tout ce qui a été passé à la fonction, vous pouvez modifier cet objet point local autant que vous voulez, l'objet original de l'appelant ne sera pas affecté. Il n'y a aucun moyen de changer ce comportement avec les paramètres passe par valeur.


2. Les références aux objets (passage par référence):

void cp(point& p);

est passée par référence. L'objet réel est passé à la fonction est disponible (et potentiellement sujettes à modification) à l'intérieur de la fonction. Si vous ne voulez pas la fonction d'être en mesure de changer le passé en objet, déclarer le paramètre comme const point&:

void cp(const point& p);

3. Les pointeurs vers les objets (passage par référence):

void cp(point* p);

est le passage par référence également, avec quelques différences subtiles. Une différence notable est que vous pouvez passer un pointeur NULL à la fonction. Ce n'est pas possible avec des références, parce que les références doivent initialiser et ne peuvent pas être remis en place par la suite. - Comme avec les références, si vous voulez cp disallow de changer le passé en point, déclare comme const:

void cp(const point* p);

Réponse à votre question:

Paramètres de passage par valeur ne sont pas intrinsèquement mauvais en aucune façon. Bien sûr, il y a des types pour lesquels copie construction est coûteux (par exemple des objets très volumineux ou complexes), ou si elle a certains effets secondaires (par exemple avec std::auto_ptr). Dans ces cas, vous devriez faire attention. Dans le cas contraire, il est juste une autre caractéristique de C ++ qui a ses utilisations parfaitement raisonnables.

void cp(point p){
}

il devient par la valeur

void cp(point *p){
}

il obtient par référence

Comme toute autre variable de données.

Dans java le scénario est différent. objets Passing vont toujours par référence.

Dans le cas où le vous struct point est passé « en valeur », qui signifie que la structure entière est copiée. Pour les grands types de données, cela peut en effet être lent.

Vous pouvez envisager de passer l'objet par référence

void cp(point& p) // p may be altered!

ou être référence const

void cp(const point& p) // p may not be altered!

Voir les possibilités d'éviter des objets en passant par la valeur. L'objet est non seulement « copié », mais est-copie construite. Donc, cela implique d'appeler le constructeur de copie et de la chaîne des constructeurs de copie si votre objet est composé ou dérivé de plusieurs objets. Passer par référence si possible.

cp vide (point de p & const) const {

    cout << p.x << endl;
    cout << p.y << endl;

}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top