Я создаю фреймворк, который будет читать XML-файл Tiled, и результирующий объект (tpp :: File) будет чистым неизменным (без сеттеров или конструкторов копирования/операторов присваивания). В принципе, он использует идею builder pattern, но вместо того, чтобы иметь 2 объекта с одинаковыми атрибутами, у меня будет один с основными атрибутами, а другой - «обернуть» его.Неизменяемые классы и конструкторы копирования
// Represents a Tiled's TMX file. This object is immutable.
class TILEDPP_API File final
{
public:
File() = default;
File(tpp::File&&) = default;
File(const tpp::File&) = delete;
File(const tpp::Path& path, tpp::FileMetadata& metadata);
File& operator = (tpp::File&&) = default;
File& operator = (const tpp::File&) = delete;
const tpp::Path& getPath() const;
const tpp::Header& getHeader() const;
const tpp::Layers& getLayers() const;
const tpp::TileSets& getTileSets() const;
private:
const tpp::Path m_path;
tpp::FileMetadata m_metadata; // Should be const!
};
// Represents the content of a Tiled's TMX file (header, sets, layers etc).
// This struct is non-copyable due to its HUGE size.
struct TILEDPP_API FileMetadata final
{
FileMetadata() = default;
FileMetadata(tpp::FileMetadata&&) = default;
FileMetadata(const tpp::FileMetadata&) = delete;
FileMetadata& operator = (FileMetadata&&) = default;
FileMetadata& operator = (const FileMetadata&) = delete;
tpp::Header header;
tpp::Layers layers;
tpp::TileSets sets;
};
Затем, где-то в процессе создания файла, мы будем иметь это:
tpp::File FileReader::read(const std::string& path)
{
tpp::FileMetadata metadata = m_parser.parseMetadata(path);
return tpp::File(path, metadata);
}
выше фрагмент кода будет использовать File(const tpp::Path& path, tpp::FileMetadata& metadata)
конструктор, как и ожидалось. Однако, если мы создадим tpp :: File tpp :: FileMetadata, он попытается использовать вместо этого конструктор File(const tpp::File&)
, который является удален. Почему это происходит?
Для справки, проект можно найти here. Любые мысли также очень ценятся.
Hi, @Yakk! Спасибо за ваш ответ! Не могли бы вы рассказать мне об этом: 'FileMetaData не поддерживает переход из FileMetadata const &&). Таким образом, ваш = default в файле (файл &&) не работает; никакая реализация по умолчанию не может работать. Кроме того, как «добавление поддержки» для перехода из этого требует, чтобы он * удалял * оператор перемещения/операнда перемещения ?! –
@YvesHenri Где вы видите "добавление поддержки"? Кого вы цитируете? Ваш дизайн не может поддерживать перемещение; вы хотите неизменности, вы не можете поддерживать перемещение. Первоначальные комментарии о поддержке перемещения - это вывод you * want * move support; Я просто заявляю, что вы не можете этого сделать. '= Default' фактически не выполнял их; поэтому я сделал это явным, что это '= delete'd. Затем я изменил оператор return, чтобы построить вместо него место вместо возвращаемого значения. Это имеет серьезные ограничения, как я описываю до последней строки. После последней строки я говорю «хорошо, вот еще одно решение». – Yakk