Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.56
go
Эксперт С++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
#1

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

14.01.2013, 13:35. Просмотров 1184. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.01.2013, 13:35
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Виртуальный замок (C++):

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

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

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

Добавить к классу TPoint1 виртуальный метод Draw(Canvas:TCanvas), который будет выводить изображение точки - C++ Builder
Надо добавить к классу TPoint1 виртуальный метод Draw(Canvas:TCanvas), который будет выводить изображение точки. Параметром этого метода...

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

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

5
lemegeton
2925 / 1354 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
14.01.2013, 15:04 #2
Вся суть замка в том, что у класса Lock конструктор приватный.
Когда вы делаете его публичным, вся магия исчезает.
0
go
Эксперт С++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
14.01.2013, 15:09  [ТС] #3
lemegeton, смотрите третий пример. Там конструктор Lock не вызывается, значит он приватный(мы ведь использовали приватное наследование). Что я упустил?
0
lemegeton
2925 / 1354 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
14.01.2013, 17:27 #4
Цитата Сообщение от 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
Эксперт С++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
14.01.2013, 18:02  [ТС] #5
Цитата Сообщение от 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
2925 / 1354 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
14.01.2013, 22:38 #6
Цитата Сообщение от go Посмотреть сообщение
При виртуально наследовании класс последний в иерархии ответственен за вызов конструктора класса, от которого пошло виртуальное наследование. Вот тому подтверждение
Совершенно верно, это выскользнуло из моего внимания.
0
14.01.2013, 22:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.01.2013, 22:38
Привет! Вот еще темы с ответами:

Виртуальный код клавмши точка - C++ WinAPI
У меня функция winapi запрашивает виртуальный код клавиши, типа VK_KEYUP, VK_DELETE и тп. А какой код у точки - &quot;.&quot; ?

Как сделать виртуальный диск? - C++ WinAPI
Как можно создать виртуальный диск из файла-образа? Например как в PGPdisk. Если для этого нужен драйвер, то где можно почитать про это?

Asus x52d горит одновременно два индикатора "замок открыт" и "замок закрыт" - Ремонт ноутбуков
При включении ноутбука Asus x52d горит одновременно два индикатора &quot;замок открыт&quot; и &quot;замок закрыт&quot;, также &quot;лампочка&quot;- индикатор работы...

Что такое виртуальный и относительный виртуальный адрес? - Assembler
Прив. Хочу разобрать одну программку, дизассемблировал ее и начал разбиратся. При помощи API Monitor нашел адрес функции, которая...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru