Форум программистов, компьютерный форум CyberForum.ru

Член класса, создаваемый конструктором с параметром - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
17.02.2012, 13:47     Член класса, создаваемый конструктором с параметром #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
class A
{
 public:
  class B
  {
   ...
   B(A *param); // Как открыть этот конструктор классу A, но закрыть его ото всех остальных частей программы?
   ...
  };
 B b; // Как создать этот член с помощью конструктора B::B(A *param)?
 ...
};
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 13:51     Член класса, создаваемый конструктором с параметром #2
C++
1
B b(this)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A
{
 private:
  class B
  {
   ...
   B(A *param); // Как открыть этот конструктор классу A, но закрыть его ото всех остальных частей программы?
   ...
  };
B b; // Как создать этот член с помощью конструктора B::B(A *param)?
public:
 
 
A():b(this){}
 ...
};
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
17.02.2012, 13:57     Член класса, создаваемый конструктором с параметром #3
taras atavin, По идее нет таких способов... Только если сам класс private объявить.
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 14:01     Член класса, создаваемый конструктором с параметром #4
Цитата Сообщение от AzaKendler Посмотреть сообщение
его ото всех остальных частей программы?
все остальные части я так понимаю находятся вне класса А, поэтому простой private и закроет
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
17.02.2012, 14:08  [ТС]     Член класса, создаваемый конструктором с параметром #5
Так просто?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A
{
 private:
  class B
  {
   ...
   public:
   B(A *param); // Как открыть этот конструктор классу A, но закрыть его ото всех остальных частей программы?
  A & owner();
   ...
  };
public:
 A ();
 B b(this); // Как создать этот член с помощью конструктора B::B(A *param)?
 ...
};
A a;
A *p;
p=a.b.owner(); // Допустимо? Только конструктор и деструктор класса A::B должны быть закрыты внутри класса A, остальные public-члены класса A::B должны быть, но private-члены класса A::B не должны должны быть доступны даже классу A.
p=new A[4]; //p[0].b, p[1].b, p[2].b и p[3].b будут созданы с помощью конструктора с параметром? Этому конструктору при создании p[0].b будет передан фактический параметр со значением &(p[0]), при создании p[1] - со значением &(p[1]), при создании p[2] - со значением &(p[2]), а при создании p[3] - со значением &(p[3])?
Добавлено через 37 секунд
Цитата Сообщение от AzaKendler Посмотреть сообщение
все остальные части я так понимаю находятся вне класса А, поэтому простой private и закроет
Закрыть надо только конструктор и деструктор, а не весь класс A::B.
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
17.02.2012, 17:04     Член класса, создаваемый конструктором с параметром #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A
{
public:
    class B
    {
        friend class A;
        B(A* a):owner_(*a){}
        
    public:
        A&
        owner() const { return owner_; }
 
    private:
        A& owner_;
    };
 
    A() : b1(this), b2(this) { }
 
private:
    B b1;
    B b2;
};
Bers
Заблокирован
17.02.2012, 17:42     Член класса, создаваемый конструктором с параметром #7
C++
1
2
3
4
5
6
class A
{
public:     A() { b1.pOwner=this; b2.pOwner= this; }
private:    struct B   {    A* pOwner;    };
private:    B b1, b2;
};
Объявленный в приватной области класса, подкласс уже будет недоступен никому извне.
Самим типом данных этого подкласса воспользоваться будет нельзя. Таким образом, класс-хозяин будит единственный клиент этого класса. Так же, это означает, что выполнять защиту доступа вложенных классов просто не имеет смысла.
(с другой стороны, смысла во вложенных классах в принципе не очень то много)

retmas
Толкать в списках инициализации конструкторов this объекта - не очень хорошая идея.

C++
1
2
3
4
5
6
A() : b1(this), b2(this)  //Конструктор объекта ещё не отработал. 
      //Объект ещё не создан. 
      //Попытка использовать this несуществующего объекта - UB
{
   //вот здесь this объекта уже корректный
}
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
17.02.2012, 18:10     Член класса, создаваемый конструктором с параметром #8
Цитата Сообщение от Bers Посмотреть сообщение
Толкать в списках инициализации конструкторов this объекта - не очень хорошая идея.
это зависит...

Добавлено через 2 минуты
если потом в конструкторе используется b1 (или b2) - то да. имеем траблы.
если нет - вполне безопасно

Добавлено через 2 минуты
если имеет место первый случай, то конечно лучше
C++
1
2
3
4
5
A()
{
    b1 = new B(this);
    b2 = new B(this);
}
Bers
Заблокирован
17.02.2012, 18:16     Член класса, создаваемый конструктором с параметром #9
Цитата Сообщение от retmas Посмотреть сообщение
если...
Мина замедленного действия.

"Предок инициализируется потомком" - просто вдумайтесь в эту фразу.
Такая архитектура больше смахивает на спагетти.
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
17.02.2012, 18:29     Член класса, создаваемый конструктором с параметром #10
Цитата Сообщение от Bers Посмотреть сообщение
Мина замедленного действия.

"Предок инициализируется потомком" - просто вдумайтесь в эту фразу.
Такая архитектура больше смахивает на спагетти.
мой код и не претендует на код "на все случаи жизни". я лишь показал идею ТСу. а говоря о конкретной реализации(выше) - исходя из вышесказанного, опыта и поставленных задач, ТСу решать: использовать ее, использовать решение в следующем комменте(new в конструкторе) или сделать ее как-то по-своему.

Добавлено через 5 минут
Цитата Сообщение от Bers Посмотреть сообщение
Такая архитектура больше смахивает на спагетти.
такое спагетти зачастую бывает стандартным решением для установления связи агрегируемого объекта с агрегирующим
Bers
Заблокирован
17.02.2012, 18:39     Член класса, создаваемый конструктором с параметром #11
Цитата Сообщение от retmas Посмотреть сообщение
такое спагетти зачастую бывает стандартным решением для установления связи агрегируемого объекта с агрегирующим
Приведите пример подобных "стандартных" решений.
Я конечно сталкивался с ситуациями, когда очень хотелось инициализировать предка потомком.
Но во всех этих ситуациях находились более простые и безопасные решения.

C++
1
2
3
4
5
class A
    {
        struct B {  void Init(A& agent){ ... }  } b;    
    public:  A() {  b.Init(*this); }
    };
Закрыть ото всех конструктор класса - значит ограничить количество клиентов класса до одного класса-хозяина. В этих условиях абсолютно бессмысленно инициализировать детку вперёд батьки.
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
17.02.2012, 18:47     Член класса, создаваемый конструктором с параметром #12
причем тут инициализация предка потомком? мы просто устанавливаем связь между ними. ни о какой инициализации предка потомком нет речи. о примерах... Qt изобилует примерами подобного установления связи
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 18:54     Член класса, создаваемый конструктором с параметром #13
Bers, ты же сам отписывал в смежной теме, что указатель на адрес класса показывает на его нулевой байт. т.е. this - это просто адрес "начала" А. если А не будет создан то А нельзя будет использовать. Поскольку B находится внутри A, если A не создался доступ к B мы не получим на уровне языка.
приведи пример опасности плиз
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
17.02.2012, 19:07  [ТС]     Член класса, создаваемый конструктором с параметром #14
Цитата Сообщение от retmas Посмотреть сообщение
friend class A;
Это я знаю, но так классу A откроются всеprivate-члены.

Добавлено через 1 минуту
Цитата Сообщение от retmas Посмотреть сообщение
private:
* * B b1;
* * B b2;
А надо public.

Добавлено через 4 минуты
Цитата Сообщение от Bers Посмотреть сообщение
Самим типом данных этого подкласса воспользоваться будет нельзя.
Закрыть надо только конструктор и деструктор: задача просто блокировать возможность существования экземпляров класса A::B вне экземпляров класса A, то есть гарантировать, что любой экземпляр класса A::B будет членом класса A, но при этом сами экземпляры класса A::B и все public члены класса A::B должны быть доступны извне, а private-члены класса A::B должны быль доступны только из самого класса A::B и недоступны из класса A.

Добавлено через 1 минуту
Цитата Сообщение от retmas Посмотреть сообщение
b1 = new B(this);
То есть выделять их динамически по указателям. Спасибо, не надо.

Добавлено через 1 минуту
Цитата Сообщение от Bers Посмотреть сообщение
"Предок инициализируется потомком" - просто вдумайтесь в эту фразу.
Такая архитектура больше смахивает на спагетти.
Здесь не наследование, а агрегация.
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
17.02.2012, 19:08     Член класса, создаваемый конструктором с параметром #15
Цитата Сообщение от taras atavin Посмотреть сообщение
Это я знаю, но так классу A откроются всеprivate-члены.
сделайте дружественным только конструктор.
Цитата Сообщение от taras atavin Посмотреть сообщение
А надо public.
ну так сделайте их паблик
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A
{
public:
    A() : b1(this), b2(this) { }
 
    class B
    {
        friend A::A(); // теперь только A::A() имеет доступ к приватным данным
        B(A* a):owner_(*a) {}
        
    public:
        A&
        owner() const { return owner_; }
 
    private:
        A& owner_;
    };
 
    B b1;
    B b2;
};
Bers
Заблокирован
17.02.2012, 19:08     Член класса, создаваемый конструктором с параметром #16
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от AzaKendler Посмотреть сообщение
Bers, ты же сам отписывал в смежной теме, что указатель на адрес класса показывает на его нулевой байт. т.е. this - это просто адрес "начала" А. если А не будет создан то А нельзя будет использовать. Поскольку B находится внутри A, если A не создался доступ к B мы не получим на уровне языка.
приведи пример опасности плиз
Пока конструктор класса не отработал, нельзя полагаться на валидность значений данных-членов экземпляра этого класса.

И в этом аспекте, тема исключений брошенных в конструкторах участников инициализации заслуживает отдельного рассмотрения.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
17.02.2012, 19:10  [ТС]     Член класса, создаваемый конструктором с параметром #17
Цитата Сообщение от retmas Посмотреть сообщение
сделайте дружественным только конструктор.
То есть?
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
17.02.2012, 19:16     Член класса, создаваемый конструктором с параметром #18
Цитата Сообщение от Bers Посмотреть сообщение
нельзя полагаться на валидность значений данных-членов экземпляра этого класса
для установления таких связей нам и не нужно на это полагаться. мы вообще эти значения не используем. а то, что не следует использовать эти значения каким-либо образом я уже ранее писал
Цитата Сообщение от taras atavin Посмотреть сообщение
То есть?
написал же (код выше)
Цитата Сообщение от retmas Посмотреть сообщение
friend A::A(); // теперь только A::A() имеет доступ к приватным данным
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
17.02.2012, 19:35     Член класса, создаваемый конструктором с параметром #19
Цитата Сообщение от Bers Посмотреть сообщение
Пока конструктор класса не отработал, нельзя полагаться на валидность значений данных-членов экземпляра этого класса.
ну а как ты положишься на них в этом конкретном случае. B закрыт. вызван может быть только изнутри А. пока А не создан до конца изнутри А ничего вызвано не будет,в этом конкретном примере. снаружи вызывать нечего.
Т.е. даже если в этом случае мы передали B указатель на начало А а потом все обвалилось и А не создался - то и обратится к "несозданным" членам просто некому.
мне кажется что в этом конкретном случае когда B закрыт. опасности нет.

Добавлено через 11 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A
{
 public:
     int val;
  class B
  {
  public:
      int z;
      int* p;
      B(A *param):z(param->val),p(param->pz){} //вот опасно pz == 0xcccccccc
  
  };
  A ():val(555),b(this),pz(new int [100]){}
  B b;
  int* pz;
~A(){delete []pz;}
};
память в куче еще не выделилась, т.е. pz еще не инициализирован, но он уже ушел в B.

Но мы разбирали совсем другой пример
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2012, 19:52     Член класса, создаваемый конструктором с параметром
Еще ссылки по теме:

C++ Пример класса с конструктором и деструктором, создание экземпляра класса через конструктор с параметрами
Не создается указатель из-за базового класса с конструктором C++
Создание массива класса, с установленным конструктором C++

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

Или воспользуйтесь поиском по форуму:
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
17.02.2012, 19:52     Член класса, создаваемый конструктором с параметром #20
думаю, если бы ТС обозначил, чего он хочет добиться, какого поведения/логики, дискуссия была бы короче, а может и не имела бы места быть. а так каждый додумывает свое и тащит одеяло на себя
Yandex
Объявления
17.02.2012, 19:52     Член класса, создаваемый конструктором с параметром
Ответ Создать тему
Опции темы

Текущее время: 03:20. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru