2013-05-14 10 views
5

Jestem tutaj patrząc na jakiś kod C++ i nie rozumiem czegoś. Jest to nieistotne, ale pochodzi z samouczka YARP (robot middleware), który pasuje do dokumentacji.Subscripting a reference to const

virtual void getHeader(const Bytes& header) 
{ 
    const char *target = "HUMANITY"; 
    for (int i=0; i<8 && i<header.length(); i++) 
    { 
    header.get()[i] = target[i]; 
    } 
} 

Nagłówek jest teraz odniesieniem do stałej i dlatego nie można go modyfikować w ramach tej funkcji. get jest na nim wywoływany, jego prototyp to char *get() const;. W jaki sposób można subskrybować i modyfikować header.get()? Program kompiluje się dobrze. Być może nie zrozumiałem, co się tutaj dzieje, ale opieram się na tym, co przeczytałem w C++ Primer ...

Bardzo doceniam małe wyjaśnienie!

Miłego dnia,

+0

'char * get() const;' oznacza, że ​​wskaźnik do znaku nie może być modyfikowany. pointee może być. – octoback

+1

myślisz o "char * const get()". "Const" po prawej stronie funkcji oznacza "nie modyfikuje niepodlegających zmianom członów" – kfsone

Odpowiedz

0

Kto zaprojektował interfejs zdecydował, że treść const Byte obiektu mogą być modyfikowane przez wartości farszu do niego. Prawdopodobnie zrobili wszystko, czego potrzebowali, aby dokonać modyfikacji. Nie użyłbym tego kodu jako przykładu dobrego projektu interfejsu.

+0

W porządku, doszedłem do wniosku, że wyraźnie nie było to optymalne kodowanie. Wkopałem się nieco głębiej i okazało się, że 'get()' zwraca atrybut o nazwie 'data', który jest" char * ". Funkcja 'get()' była rzeczywiście const, ale zwracała coś, co nie było. – technimage

0

header.get() powinien zwrócić char*, przyjmując, że jest to adres bazowy i indeksowany z [i], a ciąg znaków w target został skopiowany do tej lokalizacji.

@antitrust pod warunkiem, że dobry punkt, adres zwrotny nie może być modyfikowany przez zawartość adresu może np.

char x[100]; 
char* get() const 
{ 
    return x; 
} 

funkcja int wywołujący można zrobić tak:

get()[i] = target[i]; 

skopiuje target ciąg x, metoda ta może być przydatna, gdy x jest prywatny członek do klasy, a podczas kopiowania w x.

Edit jeśli get() jest funkcją a inline function następnie wywołanie get() w pętli nie będą wpływać na wydajność., To znaczy takich funkcja powinna być zdefiniowana inline.

+0

Ale dlaczego "const Bytes & header" nie zabrania zapisu do wewnętrznych elementów danych z 'header'? – Vorac

+0

@Vorac 'const Bytes &' oznacza odniesienie do const, nie można zmienić stałej. zobacz tutaj [odniesienie do wskaźnika] (http://stackoverflow.com/questions/15995463/in-function-declaration-return-type/15995482#15995482) jako typ zwrotu –

+0

Nie jest zdefiniowany w linii. Zaczynam to wszystko, dzięki wam wszystkim! – technimage

0

Patrząc na doc:

struct Bytes { 
    char* get() const; // works 
    char*& get() const; // would not work 
    char* mem_; 
}; 

Ten kod jest całkowicie poprawny, mimo że jest złą praktyką. Problem polega na tym, że tworzona jest kopia wskaźnika, a stałość klasy to lost. constness w C++ jest w dużej mierze koncepcyjne i łatwe do złamania (często nawet bez konsekwencji). Złożyłbym skargę na wykonawcę . Powinno to wyglądać tak:

struct Bytes { 
    char* get(); // works 
    const char* get() const; // would not work 
    char* mem_; 
}; 
1
char *get() const; 

Prawa ręka const oznacza „ten element nie zmienia niczego w klasie, która nie jest zmienny”, a to, że cześć - nie zmienia się nic. Implementacja jest prawdopodobnie podobna do tej:

char *Bytes::get() const 
{ 
    return const_cast<char *>(m_bytes); 
} 

Wskaźnik, który jest zwracany, jest jednak prostym "znakiem *".Pomyśl o tym w ten sposób:

(header.get())[i] = target[i]; 
// or 
char* p = header.get(); 
p[i] = target[i]; 
+0

Dokładnie zwraca char * a nie const char *. –