powered by simpleCommunicator - 2.0.27     © 2024 Programmizd 02
Map
Форумы / C++ [игнор отключен] [закрыт для гостей] / Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
16 сообщений из 16, страница 1 из 1
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095383
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пытаюсь ограничить права на создание копий объектов, наделив этоим правом только специальный friend-класс, не создавая специальных clone-методов внутри классов иерархии. Если в иерархию внести STL-контейнер, все ломается, даже несмотря на дружбу с ним. Если раскомментить любую из строк, выделенных желтым, ловлю ошибку компиляции. Существует ли решение такой задачи? Нужно копать в сторону аллокаторов для вектора?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
#include <vector>

struct CopyMaker {
    template<typename T>
    static T make(const T& Source) {
        return T(Source);
    };
};

class Folder;

class File {
public:
    File() : value{ 0 } {}
    ~File() {};

    File(File&& rhs) = default; // Перемещающий конструктор
    File& operator= (File&& rhs) = default; // Оператор перемещающего присваивания
    File& operator= (const File& rhs) = delete; // Оператор копирующего присваивания

    // отношения дружбы
    friend class CopyMaker;
    friend class Folder;
    friend class std::vector<File>;

private:
    File(const File& rhs) = default; // Копирующий конструктор
    int value;
};

class Folder {
public:
    explicit Folder(int Count, int s) : count{ Count } {}
    Folder(Folder&& rhs) = default; // Перемещающий конструктор
    Folder& operator= (Folder&& rhs) = default; // Оператор перемещающего присваивания
    Folder& operator= (const Folder& rhs) = delete; // Оператор копирующего присваивания
    ~Folder() {}
    File file;
    //std::vector<File> puzzles; // ЕСЛИ РАСКОММЕНТИТЬ, ЛОВЛЮ ОШИБКУ КОМПИЛЯЦИИ
    friend class CopyMaker;
private:
    int count;
    Folder(const Folder& rhs) = default; // Копирующий конструктор
};
int main() {
    {
        File file0;
        File file1(std::move(CopyMaker::make(file0)));
    }
    {
        Folder folder0(0, 10);
        Folder folder1(std::move(CopyMaker::make(folder0)));
    }

    {
        std::vector<File> f0;
        //std::vector<File> f1(f0); // ЕСЛИ РАСКОММЕНТИТЬ, ЛОВЛЮ ОШИБКУ КОМПИЛЯЦИИ
    }

    return 0;
}


VS 2019
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Severity	Code	Description	Project	File	Line	Suppression State
Error	C2248	'File::File': cannot access private member declared in class 'File'	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\xmemory	695	
Message		see declaration of 'CopyMaker'	test	D:\Files\tmp\cpp\test\main.cpp	3	
Message		see declaration of 'CopyMaker'	test	D:\Files\tmp\cpp\test\main.cpp	3	
Message		see declaration of 'File'	test	D:\Files\tmp\cpp\test\main.cpp	12	
Message		see declaration of 'File::File'	test	D:\Files\tmp\cpp\test\main.cpp	27	
Message		see reference to class template instantiation 'std::vector<File,std::allocator<File>>' being compiled	test	D:\Files\tmp\cpp\test\main.cpp	56	
Message		see reference to function template instantiation 'File *std::vector<File,std::allocator<File>>::_Ucopy<File*>(_Iter,_Iter,File *)' being compiled	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\vector	534	
Message		see reference to function template instantiation 'File *std::vector<File,std::allocator<File>>::_Ucopy<File*>(_Iter,_Iter,File *)' being compiled	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\vector	534	
Message		see reference to function template instantiation 'File *std::_Uninitialized_copy<_Iter,std::allocator<File>>(const _InIt,const _InIt,File *,_Alloc &)' being compiled	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\vector	1595	
Message		see reference to function template instantiation 'std::vector<File,std::allocator<File>>::vector(const std::vector<File,std::allocator<File>> &)' being compiled	test	D:\Files\tmp\cpp\test\main.cpp	57	
Message		see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,File&>(_Alloc &,_Objty *const ,File &)' being compiled	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\xmemory	1532	
Message		see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,File&>(_Alloc &,_Objty *const ,File &)' being compiled	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\xmemory	1533	
Message		see reference to function template instantiation 'void std::_Uninitialized_backout_al<_Alloc>::_Emplace_back<File&>(File &)' being compiled	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\xmemory	1567	
Message		see reference to function template instantiation 'void std::_Uninitialized_backout_al<_Alloc>::_Emplace_back<File&>(File &)' being compiled	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\xmemory	1567	
Message		while compiling class template member function 'std::vector<File,std::allocator<File>>::vector(const std::vector<File,std::allocator<File>> &)'	test	C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\vector	523	

GCC
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
/usr/include/c++/6/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = File; _Args = {const File&}]’:
/usr/include/c++/6/bits/stl_uninitialized.h:75:18:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const File*, std::vector<File> >; _ForwardIterator = File*; bool _TrivialValueTypes = false]’
/usr/include/c++/6/bits/stl_uninitialized.h:126:15:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const File*, std::vector<File> >; _ForwardIterator = File*]’
/usr/include/c++/6/bits/stl_uninitialized.h:281:37:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const File*, std::vector<File> >; _ForwardIterator = File*; _Tp = File]’
/usr/include/c++/6/bits/stl_vector.h:324:31:   required from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = File; _Alloc = std::allocator<File>]’
<span class="error_line" onclick="ide.gotoLine('main.cpp',43)">main.cpp:43:5</span>:   required from ‘static T CopyMaker::make(const T&) [with T = Folder]’
<span class="error_line" onclick="ide.gotoLine('main.cpp',52)">main.cpp:52:57</span>:   required from here
/usr/include/c++/6/bits/stl_construct.h:75:7: error: ‘constexpr File::File(const File&)’ is private within this context
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:27:5: note: declared private here
     File(const File& rhs) = default; // Копирующий конструктор
     ^~~~

...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095398
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad
Пытаюсь ограничить права на создание копий объектов, наделив этоим правом только специальный friend-класс,
Если вводишь friend-класс - у тебя уже ошибка.

А по сути твоих классов: убери нафиг дружбу. Добавь в иерархию класс FileSystem и пусть он и только он занимается созданием и копированием объектов. И вообще, посмотри на реальность: папки содержат файлы, но файлы не лезут к папкам. Зачем тебе внутри файла дружить с папкой совершенно не понятно.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095400
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl

А по сути твоих классов: убери нафиг дружбу. Добавь в иерархию класс FileSystem и пусть он и только он занимается созданием и копированием объектов.
И дать ему доступ к приватным членам либо добавить к каждому классу метод clone? Это решение очевидно, но мне хотелось изучить именно ту возможность копирования, что я обозначил.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095426
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,

Судя по ошибкам GCC и VS копированием в векторе занимается не он сам а вспомогательные объекты.
Значит friend class std::vector<File> бесполезен.
А также скорее всего нет кроссплатформенного способа сделать френдами эти вспомогательные объекты.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095428
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы на вашем месте заменил vector на deque. Ему копирование не нужно.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095461
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Я бы на вашем месте заменил vector на deque. Ему копирование не нужно.
Не помогает. Странность еще и в том, что вектор нормально работает с объектами, которые нельзя копировать (конструктор копий помечен как delete), но можно перемещать.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095478
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky
Судя по ошибкам GCC и VS копированием в векторе занимается не он сам а вспомогательные объекты.
Контейнеры с поддержкой аллокаторов выделяют память, создают, уничтожают объекты через аллокатор. Для того он и нужен.
Anatoly Moskovsky
А также скорее всего нет кроссплатформенного способа сделать френдами эти вспомогательные объекты.
Требования к типам суваемым в контейнер описаны через использование функций `allocator_traits`, так что попробовать можно. Но не нужно.
Модератор: Друзья. Без грубостей.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095499
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest
Требования к типам суваемым в контейнер описаны через использование функций `allocator_traits`, так что попробовать можно. Но не нужно.
Лезть к allocator_traits немытыми руками действительно не нужно. Это я про себя.
А по поводу "мается": как запретить основном коде, но разрешить создание копий в коде автотестов? Так, чтобы можно было с легкостью потом идентифицировать все места, где они создаются.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095502
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AmKad, а какой вообще смысл в копировании File? Он либо только перемещаемый, как мьютекс, либо, если там рефкаунтер, то почему копирование не разрешить всем?
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095507
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad
как запретить основном коде, но разрешить создание копий в коде автотестов?

если речь идет только о предоставлении доступа к закрытым сущностям для целей тестирования, то можно попробовать в основном коде классов объявить их члены как protected, в тестах отнаследоваться (без внесения дополнительной логики) и тестировать наследника
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095517
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad wroteкак запретить основном коде, но разрешить создание копий в коде автотестов?

Если речь идёт исключительно о защите основного кода от дурака, то или условная
компиляция, либо можно попробовать объявление конструктора как "deprecated" и
игнорирование предупреждений где надо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095530
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Если речь идёт исключительно о защите основного кода от дурака, то или условная
компиляция, либо можно попробовать объявление конструктора как "deprecated" и
игнорирование предупреждений где надо.
Да, речь именно о защите основного кода от дурака в range-based циклах. Условная компиляция да, как вариант.

a guest
AmKad, а какой вообще смысл в копировании File? Он либо только перемещаемый, как мьютекс, либо, если там рефкаунтер, то почему копирование не разрешить всем?
Имена Folder и File даны для примера. У меня некая иерархия. Тестируется сериализация ее свойств в бинарный поток и обратно. Подчеркиваю, сериализуется не сама иерархия, как таковая, а только ее свойства (то по сериализованному набору нельзя восстановить иерархию, только свойства конкретной. Поэтому в соответствующие процедуры преобразования она передается по ссылке). Для этого в тестах она создается, наполняется атрибутами. Потом с нее как с оригинала снимается const-копия, оригинал проходит цикл сериализации/десериализации и после сравнивается с const-копией. Для сравнения переопределены соответствующие операторы.

Cerebrum
AmKad
как запретить основном коде, но разрешить создание копий в коде автотестов?

если речь идет только о предоставлении доступа к закрытым сущностям для целей тестирования, то можно попробовать в основном коде классов объявить их члены как protected, в тестах отнаследоваться (без внесения дополнительной логики) и тестировать наследника
Но ведь родитель по-прежнему содержит вектор объектов базового класса.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095532
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Случайно добавил сообщение. Хотел отредактировать предыдущее. Теперь не знаю, как удалить это.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095547
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadДа, речь именно о защите основного кода от дурака в range-based циклах.

Я в таких случаях просто отбиваю конструктор копирования. Не знаю зачем оно тебе
в юнит-тестах.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095550
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дуракоустойчивость кода - это замечательная тема для пятницы.
...
Рейтинг: 0 / 0
Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
    #40095554
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Не знаю зачем оно тебе в юнит-тестах.
Чтобы было с чем сравнить.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Управление копированием иерархии объектов через спец friend-класс с шаблонной функцией
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]