2015-10-29 36 views
8

Chcę przekazać obiekt klasy A (nazwać go) przez odniesienie (w szerokim znaczeniu, tj. Przez A & lub przez A *) do konstruktora innej klasy B. I nie chcę, aby "a" było modyfikowane wewnątrz B ("a" jest tylko do odczytu i jest duże, dlatego chcę je przekazać przez odniesienie). Znam dwóch opcji:Przejście przez opcje odniesienia w C++

1) pass 'a' jak

const A & a_ 

2) Przełęcz 'a' jak

const A * a_ 

Wadą wariantu 1 jest to, że mogę błędnie zdać wartość r. Wadą opcji 2 jest to, że mogę omyłkowo przekazać zerowy wskaźnik.

Moje pytania są następujące: 1) Czy mam rację co do wad powyżej? 2) Czy istnieje inny zalecany sposób przekazania "a" przez odniesienie?

Widziałem odpowiedzi w linku poniżej. Ale jestem ciekawy, czy istnieją inne opcje niż to, co jest zamieszczone w tym pytaniu. Are there benefits of passing by pointer over passing by reference in C++?

+5

Jak prawdopodobne jest to, że będzie błędnie przekazać wartość R, i jak poważne będą skutki tego działania będzie? – emlai

+1

Jeśli masz obawy i znasz problemy, potrzebujesz sprawdzenia błędów. Przejdź przez referencję i spróbuj/złap. Jeśli zrobisz to za pomocą wskaźnika, zmodyfikujesz oryginalną instancję swojego obiektu. –

+1

Co to jest wartość rwalna? Czy to nieokreślona równość? Jak lwartość? –

Odpowiedz

18

Przejść przez const A &.

Możesz zapobiec przypadkowemu przejściu wartości r, deklarując przeciążenie rwartością tej funkcji = delete. Na przykład:

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

Jest jeden podchwytliwy problem, który wpadł mi na głowę, gdy mamy do czynienia z tym: jeśli naprawdę chcesz wyłączyć * wszystkie * wartości r, lepiej zamiast tego użyć 'void func (const A &&) = delete;'. Wygląda dziwnie i brudno, ale spełnia swoją rolę.Dzieje się tak dlatego, że w przeciwnym razie starsza wersja kodu, która zwraca wartość 'const' (nie jest zalecana, ale niestety często używana w funkcjach podobnych do fabrycznych), będzie się łączyć z' func (const &); '. Powiązane: http://stackoverflow.com/q/33244951/3093378 – vsoftco

4

Spójrz na std::reference_wrapper „s konstruktorów: http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/reference_wrapper

To ma dodatkowy usunięte konstruktor, że trwa odniesienie rvalue, więc jeśli starają się przekazać rvalue do niego, że konstruktor wygrywa rozdzielczość przeciążeniem i masz błąd.

Możesz zrobić to samo: zadeklarować konstruktory const A& i A&& i usunąć te ostatnie. Wtedy nikt nie będzie w stanie przekazać rundy.

-3

Kod:

#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

To nie kompiluje. – emlai

+0

Dlaczego? Brak struktury? –

+2

Spróbuj go skompilować, zobaczyć, jakie błędy otrzymasz i naprawić je jako pierwsze. Odpowiedź typu "tylko kod" z nieprawidłowym kodem nie jest zbyt pomocna. – emlai