2009-11-09 10 views

Odpowiedz

33

Odwołanie należy zainicjować w celu odniesienia się do czegoś; nie może nic nie mówić, więc nie możesz domyślnie utworzyć klasy, która zawiera jedną (chyba, że ​​inni sugerują, definiujesz globalną wartość "null"). trzeba będzie konstruktor, który zostanie nadany Div odnosić się do:

explicit A(Div &d) : divs(d) {} 

Jeśli chcesz, aby móc być „null”, to trzeba wskaźnik, a nie odniesienie.

+1

Generalnie nie jest prawdą, że nie można domyślnie utworzyć klasy z elementem referencyjnym. Na przykład odwołanie może być powiązane z obiektem zadeklarowanym w zasięgu obszaru nazw (obiekt "globalny", w prostszych słowach). – AnT

+1

Jak już wspomniano, możesz użyć domyślnego konstruktora, jeśli używasz predefiniowanej zmiennej (jak w moim przykładzie poniżej). –

+2

Obaj jesteście poprawni. Odradzam jednak używanie globalnej wartości "zerowej" - nie może ona być stała, więc domyślnym zachowaniem byłoby użycie obiektu globalnego, który może zmienić dowolne inne wystąpienie klasy bez powiadomienia. –

8

Z jednej strony, można” t ma odniesienie NULL. Jako drugie, wszystkie odwołania zmiennych w klasie muszą zostać zainicjalizowane w czasie budowy.

+0

jak mogę go poprawić? – aajkaltak

+0

@varun: należy zainicjować odwołanie do poprawnej instancji obiektu w momencie tworzenia (tj. W konstruktorze). – jldupont

+1

@varun: zauważ, że możesz wybrać wskaźnik, jeśli to ułatwi ci życie ... lub refaktoryzację. – jldupont

5

W "English": odniesienie dotyczy coś. Nie może odnosić się do nic nie jest (null). Dlatego odniesienia są bezpieczniejsze w użyciu niż wskaźniki.

+5

Nie tylko po angielsku. Dokładnie tak samo jest w C++. – jalf

+1

lol, miałem na myśli "regułę C++ napisaną w zwykłym języku angielskim" ;-) – Abel

12

DIV jest odniesienie, a nie wskazówka. Nie możesz ustawić go na NULL, musi wskazywać na rzeczywisty obiekt jakiegoś rodzaju. Najlepszą rzeczą do zrobienia jest prawdopodobnie zdefiniowanie statycznej/globalnej instancji Div, którą arbitralnie zdefiniujesz jako "Null Div" (ustaw jej wartość na coś, czego prawdopodobnie nigdy nie użyjesz) i zainicjuj div na to. Coś takiego:

struct Div 
{ 
    int i; 
    int j; 
}; 

Div NULL_DIV = { INT_MAX, INT_MAX }; 

class A 
{ 
    public: 
      A(); 
      Div& divs; 
}; 


A::A() : divs(NULL_DIVS) 
{ 
} 

albo, alternatywnie, po prostu zrobić div wskaźnik zamiast odniesienia.

* Zauważ, że nie możesz użyć odniesienia do const, chyba że odrzucisz constness, ponieważ domyślnie kompilator nie pozwoli ci przypisać ref do ref.

+0

inicjujesz nie const const z obiektem const. Czy to się kompiluje? – Arkadiy

+0

Ach, dobry połów, nie, nie. Zaktualizuję odpowiedź. –

3

Odniesienia muszą odwoływać się do czegoś. W języku C++ nie ma czegoś takiego, jak referencja zerowa. Jeśli element może nie mieć wartości, wówczas powinien to być wskaźnik lub boost::optional lub taki typ.

odniesienie musi być zainicjowany odniesienia ważny przedmiot.

3

Należy pamiętać, że gdy mowa jest inicjowane wskazać na coś, nie można zmienić go zwrócić do czegoś innego. Jeśli nie jest to pożądane zachowanie, należy zamiast tego użyć wskaźnika lub kopii obiektu.

1

Jak wspomniano w innych postach, referencje (Div &) nie może być null. Najprostszą zmianą, jaką możesz dokonać, jest podanie referencji w konstruktorze i zainicjowanie referencyjnego elementu.Tak,

class A 
{ 
    public: 
      A(Div& inDivs); 
      Div& divs; 

}; 

public A::A(Div& inDivs) 
: divs(inDivs) 
{} 
3

Komunikat kompilator to jedna z tych wiadomości, że nie ma sensu z punktu widzenia języka, ale ujawniają wewnętrzne funkcjonowanie kompilator, sekwencja, w której jego wewnętrzne prace logiczne.

W twoim przypadku używasz wartości r (NULL) do zainicjowania odniesienia. Gdy taka inicjalizacja jest dozwolona, ​​wartość rna jest konwertowana na obiekt tymczasowy, do którego odniesienie zostanie powiązane. Tak więc kompilator zdał sobie z tego sprawę od razu i poinformował o tym fakcie komunikatem diagnostycznym.

W rzeczywistości jednak taka sztuczka jest dozwolona tylko dla referencji const, więc Twój kod jest uszkodzony, ponieważ w naszym przypadku referencja nie jest const. Ponadto, odniesienie struct, jak w kodzie, nie może zostać zainicjowane za pomocą 01:rwartości (która ma typ integralny), więc jest również z tego powodu zepsute.

Komunikat kompilatora jest jednak mylący. Tekst komunikatu wydaje się sugerować, że inicjowanie referencji członków za pomocą obiektów tymczasowych jest nielegalne. W rzeczywistości jest to legalne w C++ (gdy powyższe problemy zostaną naprawione), chociaż nie ma to sensu. Ale, myślę, gdy kod źle sformułowane towarzyszy przynajmniej jakiś komunikat o błędzie, powinno być OK dla każdego ...

2

Jasne i proste:

Odwołanie nie może być NULL.

1
class A 
{ 
    Div & ref(Div div) { return div; } 
    public: 
     A() : divs(ref(Div())) {}; 
     Div& divs; 
}; 
+0

Chociaż ten kod może odpowiedzieć na pytanie, podanie dodatkowego kontekstu dotyczącego przyczyny i/lub odpowiedzi na pytanie może znacznie poprawić jego wartość długoterminową. Edytuj odpowiedź, aby dodać wyjaśnienie. – gevorg

0

Proponuję:

class A{ 
    std::deque<object*>& que = *(std::deque<object*> *)0; 
    // ... 
    // Of course `que` is to be assigned valid deque before using it - just like pointers... 
}; 
+1

Dodaj tekst wraz z kodem, opisujący przyczynę sugerowania. Pytanie już zawiera akceptowaną odpowiedź, więc wyjaśnienie, dlaczego twoja odpowiedź jest ważna zbyt/bardzo, bardzo by pomogło. – Banana

+0

Przykro mi, że nie rozumiem, dlaczego muszę wyjaśnić przyczynę użycia tego rozwiązania - z tym, że pokazuje, że to działa. – Bretzelus

+0

Może działać w niektórych implementacjach, ale nie jest zgodny. Jeśli chcesz wskaźnik, po prostu użyj wskaźnika, zamiast takich shenaniganów, które całkowicie naruszają intencje odniesień. –

Powiązane problemy