Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.70/79: Рейтинг темы: голосов - 79, средняя оценка - 4.70
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562

Как лучше запретить копирование объекта?

13.12.2014, 13:15. Показов 17021. Ответов 57
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть класс, надо запретить копирование его экземпляров. Можно как то сделать, чтоб в интерфейсе класса вообще не было конструктора копии и оператора копирующего присваивания?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.12.2014, 13:15
Ответы с готовыми решениями:

Как запретить копирование с флешки?
Доброе утро! Поскажите, пожалуйста, как запретить копирование с флешки? Хочу распечатать документ, но не хочу, чтобы осталась копия...

Как запретить копирование диска?
Люди добрые !!! Мучаюсь уже третий день не как не могу сделать так чтобу ДВД видео могли увидеть не не смогли копировать!!! стли...

Как обойти "запретить копирование"
Вкладка Параметры доставки - основные - галочка на запрет копирования. У получателя соответственно не получаеться распечатать, скопировать...

57
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.12.2014, 16:28  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от DrOffset Посмотреть сообщение
По первоначальной теме есть что добавить?
Есть. Есть агрегирующий конеретный класс, не являющийся предком других классов и имеющий как минимум один собственный именованный экземпляр. Все экземпляры данного класса декларируются только с помощью конструктора по умолчанию. Требуется запретить копирование экземпляров только данного класса и сделать так, чтоб всякое присваивание одного экземпляра другому было перемещающим, данные признаки не должны распространяться на потомки, если таковые появятся в будущем. Потомки копироваться должны и для них присваивание по умолчанию должно означать копирование. Нет ни какой сущности, которая могла бы объединить данный класс с каким либо другим и такая сущность не может иметь смысл.
0
 Аватар для Гром
212 / 131 / 28
Регистрация: 20.03.2009
Сообщений: 1,123
Записей в блоге: 16
14.12.2014, 16:37
Как сделать три (аналогично - десять-двадцать-сто...) класса некопируемых сущностей с минимальными затратами и с минимальным риском в одном (-двух-пятнадцати...) из них где-то случайно накосячить:
C++
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
class Human : NonCopyable
{
public:
Human(std::string firstName, std::string lastName);
std::string firstName() const;
std::string lastName() const;
private:
std::string FirstName, LastName;
};
 
class Pet : NonCopyable
{
public:
Pet(std::string Name, const Human& owner);
std::string name();
const Human& owner() const;
private:
std::string Name;
const Human& Owner;
};
 
class House : NonCopyable
{
public:
House();
void addHabitant(const Human* habitant);
void addPet(const Pet* pet);
private:
std::deque<Human*> Habitants;
std::deque<Pet*> Pets;
};
Еще остались вопросы по поводу того, зачем нужен такой NonCopyable, и как его правильно использовать?
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.12.2014, 16:49  [ТС]
Цитата Сообщение от Гром Посмотреть сообщение
Как сделать три (аналогично - десять-двадцать-сто...) класса некопируемых сущностей с минимальными затратами и с минимальным риском в одном (-двух-пятнадцати...) из них где-то случайно накосячить:
Как сделать два-сто-тысячу сущностей, содержащих поле типа std::string и с минимальным риском в одном из них где-нибудь накосячить? Не смешно. Тем более, что проще накосячить при наследовании, чем в написании одного признака.

Добавлено через 4 минуты
Цитата Сообщение от Гром Посмотреть сообщение
class Human : NonCopyable { public: Human(std::string firstName, std::string lastName); std::string firstName() const; std::string lastName() const; private: std::string FirstName, LastName; }; class Pet : NonCopyable { public: Pet(std::string Name, const Human& owner); std::string name(); const Human& owner() const; private: std::string Name; const Human& Owner; }; class House : NonCopyable { public: House(); void addHabitant(const Human* habitant); void addPet(const Pet* pet); private: std::deque<Human*> Habitants; std::deque<Pet*> Pets; };
Чёрта с два. Человека с петом нельзя объединять ни какой сущностью кроме биологического надтаксона. Учите UML. Там ясно сказано, что прежде чем создавать базовый класс для нескольких других классов, следует убедиться в том, что общие признаки этих классов есть следствие родства самих классов. А отсюда единственная допустимая сущность, объединяющая человека с собакой - млекопитающее. А если с рыбой, то позвоночное. А если ты червей разводишь, то уже животное (мы тоже в этом царстве).
Поэтому
C++
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
class Human : HumNonCopyable
{
public:
Human(std::string firstName, std::string lastName);
std::string firstName() const;
std::string lastName() const;
private:
std::string FirstName, LastName;
};
 
class Pet : PNonCopyable
{
public:
Pet(std::string Name, const Human& owner);
std::string name();
const Human& owner() const;
private:
std::string Name;
const Human& Owner;
};
 
class House : HomNonCopyable
{
public:
House();
void addHabitant(const Human* habitant);
void addPet(const Pet* pet);
private:
std::deque<Human*> Habitants;
std::deque<Pet*> Pets;
};
и тот же самый мифический риск где то накосячить добавляется к реальному риску криво унаследовать.
0
 Аватар для Гром
212 / 131 / 28
Регистрация: 20.03.2009
Сообщений: 1,123
Записей в блоге: 16
14.12.2014, 16:53
Цитата Сообщение от taras atavin Посмотреть сообщение
данные признаки не должны распространяться на потомки, если таковые появятся в будущем. Потомки копироваться должны и для них присваивание по умолчанию должно означать копирование.
Нарушение LSP, нет?
Только делать какой-нибудь некопирующий миксин к классу, и использовать его вместо самого класса.
Или что-то такого рода (не уверен, что скомпилируется, это только набросок):
C++
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
template<class T> class MaybeUncopyable
{
public:
MaybeUncopyable(const MaybeUncopyable& other)
 {
 *this = DoCopy<T>(other);
 }
MaybeUncopyable& operator=(const MaybeUncopyable& other)
 {
 *this = DoCopy<T>(other);
 }
};
 
class Man : public MaybeUncopyable<Man>
{
//...
};
template <class Man> Man& DoCopy(const Man& other)
{
char[(1 == 2) ? 1 : 0] unnamed;
return other;
}
template <class T> T& DoCopy(const T& other)
{
return other;
}
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.12.2014, 16:56  [ТС]
Цитата Сообщение от Гром Посмотреть сообщение
Нарушение LSP, нет?
Нарушение белорусского музыканта? Не смешно. Нарушение легчайшей суперсимметричной частицы? Подавно.
0
 Аватар для Гром
212 / 131 / 28
Регистрация: 20.03.2009
Сообщений: 1,123
Записей в блоге: 16
14.12.2014, 16:59
Цитата Сообщение от taras atavin Посмотреть сообщение
Человека с петом нельзя объединять ни какой сущностью кроме биологического надтаксона.
C++
1
2
3
4
5
6
7
8
9
10
11
class GameObject
{
//...
};
 
class Human : GameObject {/**/};
class Pet : GameObject {/**/};
class Car : GameObject {/**/};
class Book : GameObject {/**/};
class Star : GameObject {/**/};
class НЁХ : GameObject {/**/};
Как же я всю жизнь программировал-то?!111 Ведь человек и книга - вещи, которые в принципе не могут быть унаследованы от одного класса!!!

Добавлено через 1 минуту
Цитата Сообщение от taras atavin Посмотреть сообщение
Нарушение белорусского музыканта? Не смешно. Нарушение легчайшей суперсимметричной частицы? Подавно.
Нарушение Liskov Substitution Principle для тех, кто новичок в ООП. Смешно.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.12.2014, 17:08  [ТС]
А ни как проще нельзя было написать? Зачем обязательно нужны импортные аббревиатуры? Я то вику читать умею, но в тему может забрести кто угодно. И да, мне нужен именно не наследуемый признак.

Добавлено через 52 секунды
Цитата Сообщение от Гром Посмотреть сообщение
Как же я всю жизнь программировал-то?
Стаж программирования не означает понимания идеологии ООП.

Добавлено через 5 минут
Что у Ваших "игровых объектов" закономерно общего? Имя у человека и у пета? А я может пишу игру, в которой петы безымянны? Общие признаки/операции должны вытекать из родства классов, а не наоборот. И не надо смешивать наследование со случайным совпадением признаков не родственных сущностей, или операций над ними. Ладно ещё класс "существо", это ещё можно понять. Но звезда каким боком к человеку? Это уже не ООП.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
14.12.2014, 17:26
Цитата Сообщение от taras atavin Посмотреть сообщение
Требуется запретить копирование экземпляров только данного класса и сделать так, чтоб всякое присваивание одного экземпляра другому было перемещающим, данные признаки не должны распространяться на потомки, если таковые появятся в будущем.
Можно в потомках просто не вызывать конструктор копирования/оператор присваивания базового класса.
В изначальном сообщении, к тому же, не было подобных деталей (особенно насчет перемещения). Тут стоит отметить, что как-только мы определили в классе собственные оператор\конструктор перемещения, то присваивающие их версии автоматически помечаются как deleted. Вернуть их в строй после этого можно только явно определив, если мы этого не сделаем, то класс так и останется перемещаемым, но некопируемым. И в этом случае можно обходиться без идиомы noncopyable вообще. Естественно это применимо только к С++11, в С++03 все несколько сложнее и noncopyable пришлось бы оставить. А функции перемещения заменить на явные swap.

Вот небольшая иллюстрация на примере массива.

Добавлено через 4 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
Там ясно сказано, что прежде чем создавать базовый класс для нескольких других классов, следует убедиться в том, что общие признаки этих классов есть следствие родства самих классов.
Я же говорил, что в С++ наследование применяется для разных целей. В том числе в разрез с каноническим использованием. Читай Саттера и Мейерса. Справедливости ради стоит отметить, что приватное наследование не реализует отношение "является", о которым ты говорил, т.е. оно не предполагает родства, именно поэтому оно здесь используется. И служит только в качестве сервисного средства, чтобы заставить компилятор контролировать нужные нам свойства класса (для чего и нужны mix-ins). Так что никаких основополагающих концепций мы не нарушили этим кодом.
0
 Аватар для Гром
212 / 131 / 28
Регистрация: 20.03.2009
Сообщений: 1,123
Записей в блоге: 16
14.12.2014, 17:29
Цитата Сообщение от taras atavin Посмотреть сообщение
Что у Ваших "игровых объектов" закономерно общего? Имя у человека и у пета? А я может пишу игру, в которой петы безымянны? Общие признаки/операции должны вытекать из родства классов, а не наоборот. И не надо смешивать наследование со случайным совпадением признаков не родственных сущностей, или операций над ними. Ладно ещё класс "существо", это ещё можно понять. Но звезда каким боком к человеку? Это уже не ООП.
Человек и пет, унаследованные от GameObject - это уже другие классы, никак не связанные с унаследованными от NonCopyable, родом из другого проекта. К сожалению, у них оказались одинаковые имена с теми, другими.

Эта пятерка классов имеет общее то, что является частью абстрактной (не путать с абстрактными классами, абстрактным мышлением и абстрактным искусством!) простенькой игры. Игровые объекты могут находиться на карте, взаимодействовать друг с другом, отображаться на экране и т.п. Поскольку игра простенькая, то мы не выделяем отдельно PhysicalObject, GraphicalObject, ScryptableObject и другие, и валим весь функционал в GameObject.

К сожалению, я не могу позволить себе потратить ближайшие несколько месяцев на объяснение вам того ООП, каким оно является для меня и многих других людей, не совпадающих с вами, поэтому вынужден отправить вас гуглить информацию о данной интерпретации ООП. Данная ссылка будет хорошим началом для ваших поисков.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.12.2014, 17:31  [ТС]
Цитата Сообщение от Гром Посмотреть сообщение
Человек и пет, унаследованные от GameObject - это уже другие классы, никак не связанные с унаследованными от NonCopyable, родом из другого проекта. К сожалению, у них оказались одинаковые имена с теми, другими.
При чём здесь имена классов? Я вообще то имел ввиду поле std::string Name.
0
 Аватар для Гром
212 / 131 / 28
Регистрация: 20.03.2009
Сообщений: 1,123
Записей в блоге: 16
14.12.2014, 17:54
Цитата Сообщение от taras atavin Посмотреть сообщение
При чём здесь имена классов? Я вообще то имел ввиду поле std::string Name.
Ни в одном из этих пяти классов
C++
1
2
3
4
5
6
class Human : GameObject {/**/};
class Pet : GameObject {/**/};
class Car : GameObject {/**/};
class Book : GameObject {/**/};
class Star : GameObject {/**/};
class НЁХ : GameObject {/**/};
нет поля Name. Оно есть только в одном из девяти упомянутых мною классах (не считая тех, что в посте 44) - в другом классе Pet.
Цитата Сообщение от taras atavin Посмотреть сообщение
Что у Ваших "игровых объектов" закономерно общего? Имя у человека и у пета?
Нет у классов
C++
1
2
class Human : GameObject {/**/};
class Pet : GameObject {/**/};
никаких имен. Кличка есть у класса
C++
1
class Pet: NonCopyable;
Имя и фамилия есть у
C++
1
class Human: NonCopyable;
Между тем, два вышеупомянутых класса (и еще три других) унаследованы от GameObject.

Еще раз. Ниже представлены четыре РАЗНЫХ класса (у двух пар из них, так уж случилось, имена совпадают; но эти пары из разных проектов, и находятся в разных файлах исходного кода):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Human : HumNonCopyable
{
public:
Human(std::string firstName, std::string lastName);
std::string firstName() const;
std::string lastName() const;
private:
std::string FirstName, LastName;
};
 
class Pet : PNonCopyable
{
public:
Pet(std::string Name, const Human& owner);
std::string name();
const Human& owner() const;
private:
std::string Name;
const Human& Owner;
};
 
class Human : GameObject {/**/};
class Pet : GameObject {/**/};
Sapienti, как говорится, sat.
Dixi.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.12.2014, 18:01  [ТС]
Цитата Сообщение от Гром Посмотреть сообщение
никаких имен. Кличка есть у класса
Код C++
1
class Pet: NonCopyable;
Имя и фамилия есть у
По-английски даже название - это имя. Кроме того, прозвище (чем оно не кличка) - это тоже вид имени.
0
Заблокирован
14.12.2014, 21:31
Croessmah, гром, дураки-минусовальщики.
0
3 / 3 / 0
Регистрация: 14.07.2012
Сообщений: 86
22.07.2022, 20:57
Прошу прощения за некропост, начал изучать SFML и столкнулся с данной задачей.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class noncopyable
{
protected:
    noncopyable() {}
    ~noncopyable() {}
private: 
    noncopyable(noncopyable const & );
    noncopyable& operator=(noncopyable const &);
};
 
//.......
 
class SomeType 
    : noncopyable // класс SomeType нельзя копировать
{
};
никак не могу понять логику этих двуx строчек: (noncopyable(noncopyable const & ))и (noncopyable& operator=(noncopyable const &)), что делает первая и вторя по отдельности ?
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
22.07.2022, 21:15
Цитата Сообщение от dnscheb Посмотреть сообщение
что делает первая и вторя по отдельности ?
Просто объявляют конструктор копирования и оператор присваивания.
Объявляют их в private, поэтому никто к ним доступа не имеет и еще оставляют без реализации эти функции.
Соответственно, у наследника компилятор не будет генерировать конструктор копирования.

В С++11 вы можете сделать так:
C++
1
2
noncopyable(noncopyable const & ) = delete;
noncopyable& operator=(noncopyable const &) = delete;
Добавлено через 2 минуты
Idioms/Non-copyable Mixin
1
3 / 3 / 0
Регистрация: 14.07.2012
Сообщений: 86
22.07.2022, 21:17
Croessmah, первая строчка объявляет оператор копирования , а вторая оператор присваивания ? правильно?
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
22.07.2022, 21:17
dnscheb, да
1
3 / 3 / 0
Регистрация: 14.07.2012
Сообщений: 86
22.07.2022, 21:18
Цитата Сообщение от Croessmah Посмотреть сообщение
да
спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.07.2022, 21:18

Как запретить копирование данных с диска
Я сделал видео курс и запишу его на диск. Как мне сделать чтоб нельзя было скопировать эти данный на хард диск только просматривать с...

Как запретить копирование текста из RichtextBox в буфер обмена?
Задача такая: выводить текст на форму так, чтобы его можно было только читать. Пробовал использовать Label, но без полос прокрутки текста...

Как запретить заход одного объекта на другой?
Как запретить заход одного объекта на другой силами VS2008??? using System; using System.Collections.Generic; using...

Как запретить создание объекта в таком случае
Есть код class Component{ virtual void doSomething() = 0; }; class Object{ public: template&lt;typename T&gt;

Как запретить использование метода из объекта класса, содержащегося в классе?
class a { public: void set(int x, int y) { mX = x; mY = y; } int getX() { return mX; } int getY() { return mY; }


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
58
Ответ Создать тему
Новые блоги и статьи
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него. https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952 Инструкция внутри. Сразу отвечу: А в PvP с ним. . .
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru