Pull to refresh

Comments 30

т.е. это как-будто мы написали собственный std::vector с запрещёнными операциями копирования и создания… просто и гениально!
о, извините, господа, за мою глупую, детскую восхищённость и открытость. Впредь такого не будет.
Я вам поставил плюс, но для полноты картины вы забыли конструктор File().
that.handle = nullptr;
Эээ… А разве понятие r-value reference не подразумевает константость that?
Не подразумевает. В этом основной смысл: можно «переместить» данные из временного объекта, изменив его значение. А объявлять можно и как «const &&», и как "&&".
Насколько я понимаю, если мы не изменим that, ничего не выйдет: в that останется ненулевой handle, который будет закрыт в деструкторе, в результате чего в this окажется указатель на уничтоженный FILE.
Читайте коммент. Смысл в swap. Вы темповый объект меняете местами с инициализируемым.
А почему не так?
File(File&& that) : handle(nullptr) { *this = that; }
Можно и так, почему нет :). Код не претендует на идеальную реализацию, хотел лишь донести идею.
Кажется, это не должно копилироваться. Именованый объект не передаётся как r-value reference дальше (так он мог бы использоваться дальше), поэтому правильней писать так:
File(File&& that) : handle(nullptr) { *this = std::move(that); } 


С другой стороны вариант автора — это классическая идиома Copy-and-swap, широко применяемая для написания exception-safe operator=.
После беглого знакомства с C++11 не очень очевидна разница между move semantics и r-value references. Так понимаю что r-value reference это сама возможность сослаться на временный объект, тогда как move semantic — возможность использования ссылки на временный объект в конструкторе или присваивании. Или не так? Может кто нибудь внести ясность?
r-value reference — это новый тип, move semantics — новая идеология. Они сильно связаны, но разница очевидна — это просто разные вещи :)
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Если честно не понял к чему здесь OOP, но вот такой код компилироваться будет:
std::vector<File> files;
File file("data1.txt");
files.push_back(std::move(file));

std::move нужен показать, что можно забрать владение у объекта file.
UFO just landed and posted this here
А как будет происходить удаление объектов в вашем примере? Есть ли в Objective C сборщик мусора, или же NSMutableArray позаботится об этом?

В C++ тоже можно написать просто вот так:
std::vector<File*> files;
File* file = new File("file1.txt");
files.push_back(file);

и никаких вспомогательных сущностей не надо. Вопрос только в том, кто будет эти объекты потом удалять. Можно либо воспользоваться аналогом vector, который делает это автоматически, либо удалять вручную, либо прикрутить к C++ сборщик мусора.
UFO just landed and posted this here
Я согласен с тем, что C++ и не является чисто OOP языком, и мне это нравится :)

std::move / std::shared_ptr / std::unique_ptr / RAII используются чтобы определить время жизни ресурса и семантику владения. Это идиомы языка, которая в ООP языках со сборщиком мусора востребованы реже. Тем не менее наличие using в C#, try-with-resources в Java, SoftReference/WeakReference/PhantomReference в Java не делает их не-OOP языками.
Не думаю, что OOP язык не имеет права управлять временем жизни объектов.

Если взять строчку
files.push_back(std::move(file));

то аналогом на Objective-C могло бы быть
[files addObject:file];
[file "doNotReferenceAnymoreTheFileObjectSoOwnershipWillTransferToThFilesObject"];

UFO just landed and posted this here
>>В C++ это ещё значит буквально — «создать копию объекта и добавить».
Ну и на других языках тоже не все так просто. К примеру на питоне «Взять ссылку на объект и добавить в коллекцию».

>>files.push_back(std::move(file));
Нет. Я бы вырвал любому руки за скрытие этого факта! Такие вещи должен делать программист сознательно. Программирование это не компьютерная игра — это ответственность за многие решения принятые и принимаемые в процессе разработке.

Мы отлично понимаем, что ситуации разные бывают и именно поэтому Страуструп о многом сказал на стр.37 в своей книге «Дизайн и эволюция C++». Почитайте книгу о дизайне и многое станет кристально чистым и понятным. Другими словами не надо С++ натягивать на те вещи и проблемы, которые лучше решать с помощью других языков!
UFO just landed and posted this here
C++ ушел еще со времен 98 стандарта, посмотрите на стандартную библиотеку. Это в 80-е было модно ООП, все дела.
Но вот конкретно в этом случае никаких отклонений нет, просто FILE — объект с value-семантикой.
UFO just landed and posted this here
Дык я о чем. Термины имеют косвенное отношение к ООП, но прямое — к вашему вопросу, это вопрос этой плоскости. Ответ такой: тип File, как и любой другой дескриптор, должен вести себя как ссылка, а не перемещаться от владельца к владельцу. То есть счетчик ссылок и вперед. Снаружи объект будет выглядеть так, как вы хотите. То, что в Objective-C везде ссылки, не делает его более ООПшным.
При чем тут функциональное программирование? Говорю же — посмотрите на стандартную библиотеку. C++ перерос ООП — оно там есть, но есть куча своих паттернов и способов что-либо сделать.
UFO just landed and posted this here
UFO just landed and posted this here
Sign up to leave a comment.

Articles