Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526

Виртуальный замок

14.01.2013, 13:35. Показов 2604. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброе утро!
Возникла такая проблема. Допустим, я хочу запретить наследоваться от своего класса другим классам и получить ошибку компиляции(но не пряча при этом конструктор и деструктор в приватную секцию, и не используя С++11).
Для этого я пишу виртуальный замок (virtual lock)

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 Lock
{
    friend class Foo;
    Lock() { }
    Lock(const Lock&) { }
};
 
class Foo: virtual private Lock
{
 
};
 
class Bar: public Foo
{
 
};
 
int main()
{
    Foo foo;
    Bar bar;
    return 0;
}
http://liveworkspace.org/code/4iyvka$0
Как видим все нормально. Точнее код не скомпилировался, все как мы хотели.

Но вот я немного переделал этот код
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
class Lock
{
public:
    //friend class Foo;
    Lock() { }
    Lock(const Lock&) { }
};
 
class Foo: virtual private Lock
{
 
};
 
class Bar: public Foo
{
 
};
 
int main()
{
    Foo foo;
    Bar bar;
    return 0;
}
http://liveworkspace.org/code/3GKSYm$0
И он почему-то скомпилировался.

В чем принципиальное различие в этих двух кодах? Подскажите, пожалуйста, что я упускаю...

Добавлено через 5 минут
Т.е. в моем втором примере по прежнему конструктор Lock доступен только Foo.
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
32
class Lock
{
public:
    //friend class Foo;
    Lock() { }
    Lock(const Lock&) { }
};
 
class Foo: virtual private Lock
{
 
};
 
class Bar: public Foo
{
public:
   Bar()
      :  
      //Lock(),
      Foo()
   {
      
   }
 
};
 
int main()
{
    Foo foo;
    Bar bar;
    return 0;
}
Если раскоментировать вызов конструктора Lock из Bar, то получим ошибку. http://liveworkspace.org/code/4l9OVk$0
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.01.2013, 13:35
Ответы с готовыми решениями:

Как создать виртуальный поток и переопределить оператор <<?
Виртуальный то есть имеется ввиду не файловый и не строковый и не консольный. Впрочем, создание сего не противоречит синтаксису. Вот,...

Переменной присвоить виртуальный код клавиши
как глобально переменной key присвоить код нажатой клавиши ?

Как сделать виртуальный образ диска?
Всем привет. Возможно ли сделать виртуальный образ диска (как делает тот же daemon tools) без написания драйвера? Я имею в виду, чтобы...

5
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
14.01.2013, 15:04
Вся суть замка в том, что у класса Lock конструктор приватный.
Когда вы делаете его публичным, вся магия исчезает.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
14.01.2013, 15:09  [ТС]
lemegeton, смотрите третий пример. Там конструктор Lock не вызывается, значит он приватный(мы ведь использовали приватное наследование). Что я упустил?
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
14.01.2013, 17:27
Цитата Сообщение от go Посмотреть сообщение
Там конструктор Lock не вызывается, значит он приватный
Если что-то не вызывается, это еще не значит, что оно приватное. Кстати, конструктор Lock вызывается, но об этом ниже.

Приватным или публичным что-то может быть объявлено.
Так в языке С++ поля и методы класса (любом класса) объявляются приватными, если не указано обратное с помощью ключевого слова public.
Пример.
C++
1
2
3
4
class Lock {
    Lock() { }                 // приватный конструктор
    Lock(const Lock&) { } // приватный конструктор копирования
};
но
C++
1
2
3
4
5
class Lock {
 public: // вот из-за этого ключевого слова
    Lock() { }                 // публичный конструктор
    Lock(const Lock&) { } // публичный конструктор копирования
};
Помните, что при создании объекта вызываются конструкторы по-умолчанию всех родительских типов перед вызовом конструктора создаваемого объекта.
Пример выведет A B.
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
#include <iostream>
 
class A {
 public:
  A() {
    std::cout << "A" << std::endl;
  }
};
 
class B : public A {
 public:
  B() {
    std::cout << "B" << std::endl;
  }
};
 
 
int main(int argc, char *argv[]) {
 
  B b;
 
  std::cin.peek();
  return 0;
}
... на закуску, фишка приватного наследования только в том, что никто больше не знает о нем.
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
#include <iostream>
 
class A {
 public:
  A() {
    std::cout << "A" << std::endl;
  }
};
 
class B : private A {
 public:
  B() {
    std::cout << "B" << std::endl;
  }
};
 
 
int main(int argc, char *argv[]) {
  srand(time(0));
 
  B *b = new B();
  A *a = b; // фейл, наследование B от А скрыто, "A is an inaccessible base of B" 
 
  std::cin.peek();
  return 0;
}
Добавлено через 6 минут
Ах да, вот еще.
Наследоваться от залоченного таким образом класса можно. Его инстанцировать не выйдет.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
14.01.2013, 18:02  [ТС]
Цитата Сообщение от lemegeton Посмотреть сообщение
... на закуску, фишка приватного наследования только в том, что никто больше не знает о нем.
При виртуально наследовании класс последний в иерархии ответственен за вызов конструктора класса, от которого пошло виртуальное наследование. Вот тому подтверждение
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 Lock
{
    friend class Foo;
    Lock() { }
    Lock(const Lock&) { }
};
 
class Foo:  private Lock
{
 
};
 
class Bar: public Foo
{
 
};
 
int main()
{
    Foo foo;
    Bar bar;
    return 0;
}
http://liveworkspace.org/code/82Cr9$0 Конструктор приватный, но фэйла не произошло. Так конструктор класса Lock приватный, но он виден классу Foo.


Цитата Сообщение от lemegeton Посмотреть сообщение
Если что-то не вызывается, это еще не значит, что оно приватное. Кстати, конструктор Lock вызывается, но об этом ниже.
См. выше в этом же посту.

Цитата Сообщение от lemegeton Посмотреть сообщение
public: // вот из-за этого ключевого слова
Цитата Сообщение от go Посмотреть сообщение
class Foo: virtual private Lock
Вот мы его снова сделали для наслелдуемых классов от Foo приватным(т.е. для Bar конструктор Lock приватный).
1
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
14.01.2013, 22:38
Цитата Сообщение от go Посмотреть сообщение
При виртуально наследовании класс последний в иерархии ответственен за вызов конструктора класса, от которого пошло виртуальное наследование. Вот тому подтверждение
Совершенно верно, это выскользнуло из моего внимания.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.01.2013, 22:38
Помогаю со студенческими работами здесь

Виртуальный метод в классах
У меня стоит задача: Write four classes to implement the printing of different kinds of trees (they should consist of very simple ASCII...

Обязательно ли переопределять виртуальный метод в дочернем классе?
Вопрос: если в родительском классе определен и реализован виртуальный метод, обязательно переопределять его в дочернем? class OneTwo { ...

Виртуальный контекст
Господа я так понимаю это должно быть виртуальное окно?Вопрос как сделать виртульное окно и то , что мы туда нарисум перенести на наше...

Виртуальный режим в ListView
Добрый день! Задача состоит в том, чтобы считать данные файла любого размера и вывести их в hex на экран. С файлом работаю через...

Виртуальный режим в ListView
Добрый день! Задача состоит в том, чтобы считать файл и вывести его содержимое в hex на экран. Вывожу в listview. На данный момент не...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru