LinuxForum.Fans
Тема

ошибка в с++

Автор: merlin 7 сообщений 1801 просмотров
#313672

Здравствуйте уважаемые гуру. Я решил поизучать с++ на досуге, читаю книгу "C++ базовый курс" написанную Гербертом Шилдтом, третье издание. На стр 338 можно найти программу, иллюстрирующую перегрузку операторов:

text

#include <iostream>
#include <cstring>
class sample
{
    char *s;
public:
    sample();
    sample(const sample &ob);
    ~sample(){if(s) delete [] s; std::cout << "deallocating memory\n";}
    void show(){std::cout << s << "\n";}
    void set(char *str);
    sample operator=(sample &ob);
};

sample::sample() { s=new char('\0'); std::cout << "constructor called\n"; }

sample::sample(const sample &ob) { s =new char[strlen(ob.s)+1]; strcpy(s, ob.s); std::cout << "copy constructor called\n"; }

void sample::set(char *str) { if (strlen(s) > strlen(str)) { delete [] s; s = new char[strlen(str)+1]; } strcpy(s, str); } sample sample::operator=(sample &ob) { if (strlen(ob.s) > strlen(s)) { delete [] s; s = new char[strlen(ob.s)+1]; } strcpy(s, ob.s); std::cout << "redefined operator called\n"; return *this; }

sample input() { char instr[80]; sample str; std::cout << "enter string\n"; std::cin >> instr; str.set(instr); return str; }

int main() { sample ob; ob=input(); ob.show(); return 0; }

Попытка скомпилировать выдает такое:

text

ya@shvabra:/mnt/maindisk/cpp$ g++ test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:63: error: no match for ‘operator=’ in ‘ob = input()()’
test.cpp:38: note: candidates are: sample sample::operator=(sample&)
ya@shvabra:/mnt/maindisk/cpp$

Что я делаю не так?

#313690
"merlin⇓" написал:
Что я делаю не так?

operator= должен принимать константную ссылку. т.е.:
sample::operator=(const sample &ob)
так сделать правильно ... возможно у шилдта просто описка... точно также как и operator=() в 9-ти случаях из 10-ти должен возвращать константную ссылку...
но почему текущий вариант с точки зрения языка ошибочен сказать я не возьмусь...

#313699
"Fat-Zer⇓" написал:
sample::operator=(const sample &ob)

Спасибо, так все работает.

"Fat-Zer⇓" написал:
так сделать правильно ...

Ok, запомню на будущее.

"Fat-Zer⇓" написал:
возможно у шилдта просто описка... точно также как и operator=() в 9-ти случаях из 10-ти должен возвращать константную ссылку...

Не исключено что Шилдт работает с каким либо другим компилятором, например встроенным в вижуал студио. Возможно что там код будет работать без модификаций, но так как у меня нету виндовс то проверить не могу.

"Fat-Zer⇓" написал:
но почему текущий вариант с точки зрения языка ошибочен сказать я не возьмусь...

Ну если никто не предложит никаких соображений по этому поводу будем пока считать это особенностью синтаксиса.

P.S. на http://www.cplusplus.com/forum/general/5426/ обсуждают вроде бы похожую проблему, но я не смог разобраться что имеют в виду авторы.

#313741
"merlin" написал:
Не исключено что Шилдт работает с каким либо другим компилятором, например встроенным в вижуал студио.

А в начале книги не указывается, какие компиляторы использовались?

#313742
"merlin⇓" написал:
Не исключено что Шилдт работает с каким либо другим компилятором, например встроенным в вижуал студио. Возможно что там код будет работать без модификаций, но так как у меня нету виндовс то проверить не могу.

не в компиляторе дело, это должно быть в стандарте описано... видимо, тов. Герберт писал свои записки довольно давно, когда стандарт ещё не допили, а при переизданиях всё не поправил... или просто подложил свинью, мол пусть люди подумают...

"Fat-Zer⇓" написал:
точно также как и operator=() в 9-ти случаях из 10-ти должен возвращать константную ссылку...

s/константную ссылку/ссылку/

"merlin⇓" написал:
Ну если никто не предложит никаких соображений по этому поводу будем пока считать это особенностью синтаксиса.P.S. на http://www.cplusplus.com/forum/general/5426/ обсуждают вроде бы похожую проблему, но я не смог разобраться что имеют в виду авторы.

если просто, то передача по обычной ссылке(приведению к не константнй ссылке) требует изменяемого объекта(lvalue), а временный объект, возвращаемый input() таковым не является (т.е. rvalue). как-то так.

#313777
"Fat-Zer" написал:
если просто, то передача по обычной ссылке(приведению к не константнй ссылке) требует изменяемого объекта(lvalue), а временный объект, возвращаемый input() таковым не является (т.е. rvalue). как-то так.

Хм, нашел такое определение rvalue и lvalue(на http://thbecker.net/articles/rvalue_references/section_01.html ):
"An lvalue is an expression that refers to a memory location and allows us to take the address of that memory location via the & operator. An rvalue is an expression that is not an lvalue. "
Как я понял, если у нас есть rvalue объект то мы не можем узнать его адрес и следовательно ссылки на такой объект смысла не имеют. Но если это так, то каким образом добавление слова const исправляет ситуацию?

"Vitri" написал:
А в начале книги не указывается, какие компиляторы использовались?
"Fat-Zer" написал:
не в компиляторе дело, это должно быть в стандарте описано... видимо, тов. Герберт писал свои записки довольно давно, когда стандарт ещё не допили, а при переизданиях всё не поправил... или просто подложил свинью, мол пусть люди подумают...

Про компилятор в книге ничего не говорится, но автор хвалит винду.
Кроме того, на http://www.cplusplus.com/forum/general/5426/ где обсуждается подобная проблема люди утверждают что в вижуал студио все работает без добавления "const", в то время как на линуксах не работает. Так что не знаю.

#313972
"merlin⇓" написал:
Как я понял, если у нас есть rvalue объект то мы не можем узнать его адрес и следовательно ссылки на такой объект смысла не имеют.

это скорее мнемоническое правило, чтобы отличить одно от другого... и то е совсем правильное: константа это тоже rvalue.

"merlin⇓" написал:
Как я понял, если у нас есть rvalue объект то мы не можем узнать его адрес и следовательно ссылки на такой объект смысла не имеют. Но если это так, то каким образом добавление слова const исправляет ситуацию?

ссылки — это особый встроенный объекты, а не адреса. они работают примерно по таким правилам:
1) обычную ссылку можно инициировать только lvalue.
2) константную ссылку можно инициировать rvalue.
3) lvalue всегда можно привести к rvalue.

"merlin⇓" написал:
Кроме того, на http://www.cplusplus.com/forum/general/5426/ где обсуждается подобная проблема люди утверждают что в вижуал студио все работает без добавления "const", в то время как на линуксах не работает. Так что не знаю.

что тут скажешь... msvc всегда клал болт на стандарты...

Войдите или зарегистрируйтесь, чтобы ответить.