2015-10-29 3 views
8

Je souhaite passer un objet de classe A (appelez-le a) par référence (au sens large, soit A & ou par A *) au constructeur d'une autre classe B. ne veut pas que 'a' soit modifié à l'intérieur de B ('a' est en lecture seule et il est grand en taille, c'est pourquoi je veux le passer par référence). Je sais que deux options:Passage par les options de référence en C++

1) Pass 'a' comme

const A & a_ 

2) Passe 'a' comme

const A * a_ 

L'inconvénient de l'option 1 est que je peux passer par erreur une valeur-r. L'inconvénient de l'option 2 est que je peux passer par erreur un pointeur nul.

Mes questions sont: 1) Ai-je raison sur les inconvénients ci-dessus? 2) Y a-t-il une autre façon de passer 'a' par référence?

J'ai vu les réponses dans le lien ci-dessous. Mais je suis curieux de savoir s'il existe d'autres options que ce qui est affiché dans cette question. Are there benefits of passing by pointer over passing by reference in C++?

+5

Comment est-il probable que vous passerez par erreur une valeur r, et comment les conséquences de cette action sera GRAVE? – emlai

+1

Si vous avez vos soucis, et vous connaissez les problèmes, vous avez besoin d'une vérification d'erreur. Passer par référence et et essayer/attraper. Si vous le faites par un pointeur, vous allez modifier l'instance d'origine de votre objet. –

+1

Qu'est-ce qu'une rvalue? Est-ce une égalité indéfinie? Comme une lvalue? –

Répondre

18

Passez par const A &.

Vous pouvez empêcher le dépassement accidentel de valeurs en déclarant une surcharge de cette fonction = delete. Par exemple:

struct A { }; 

void func(const A & a) { } 
void func(A && a) = delete; 

int main() 
{ 
    A a; 
    func(a); // compiles 
    func(A()); // doesn't compile 
} 
+1

Il y a un problème épineux sur lequel je suis tombé: si vous voulez vraiment désactiver * all * rvalues, il vaut mieux utiliser 'void func (const A &&) = delete;' à la place. Ça a l'air bizarre et sale, mais ça fait l'affaire.C'est parce que sinon le code hérité qui renvoie par la valeur 'const' (non recommandé, mais malheureusement fréquemment utilisé dans les fonctions de type usine) se liera à' func (const &); 'à la place. Similaire: http://stackoverflow.com/q/33244951/3093378 – vsoftco

4

Jetez un oeil à std::reference_wrapper « s constructeurs: http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/reference_wrapper

Il a un constructeur supprimé supplémentaire qui prend référence rvalue, donc si vous essayez de passer un rvalue à lui, que le constructeur gagne la résolution de surcharge et vous obtenez une erreur.

Vous pouvez faire la même chose: déclarer à la fois les constructeurs const A& et A&&, et supprimer ce dernier. Alors personne ne pourra passer dans une valeur.

-3

Le code:

#include <iostream> 
using namespace std; 

struct A 
{ }; 

int func_one(A& var) { 
    A * insertVal=new A; 
    if (&var==nullptr) 
     return 0; 
    else 
     return 1; 
} 

int main() { 
    A refVar; 
    int x; 
    x=func_one(refVar); 

    return 1; 
} 
+2

Cela ne compile pas. – emlai

+0

Pourquoi? Pas de structure? –

+2

Essayez de le compiler, de voir quelles erreurs vous obtenez et de les corriger en premier. Une réponse avec code uniquement avec un code incorrect n'est pas très utile. – emlai