powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / хитрое создание объектов в объекте
25 сообщений из 27, страница 1 из 2
хитрое создание объектов в объекте
    #33480303
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
struct PARENT;
struct CHILD
{
 PARENT *parent;
 CHILD(PARENT *p)
 {
   parent=p;
 };
};


struct PARENT
{
 CHILD c1(this);//вот как-то чтобы в конструктор автоматом передался
 CHILD c2(this);//создаваемый объект PARENT
};

или придется делать так?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
struct PARENT;
struct CHILD
{
 PARENT *parent;
};


struct PARENT
{
 CHILD c1;
 CHILD c2;
 PARENT()
 {
   c1.parent=this;
   c2.parent=this;
 };
};

честно говоря мне второй вариант кажется некрасивым, а я привык что в С++ красивые решения должны преобладать над некрасивыми.
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33480377
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
по мне главное что бы решение было эффективно, а красивости ф топку
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33480381
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
эффективность один из компонентов красоты :)
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33483536
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Первый вариант прокатит. Только я не понял второго куска -


struct PARENT
{
CHILD c1(this);//вот как-то чтобы в конструктор автоматом передался
CHILD c2(this);//создаваемый объект PARENT
};

- это невалидный код.
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33483665
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чего сделать то пытаетесь? А то ссылка на потомка в базовом классе - это как-то странно выглядет :)
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33484099
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я хочу чтобы при создании PARENT автоматически создавался объект CHILD
но это возможно только с конструктором по умолчанию.
а мне хочется чтобы автоматически вызывался параметризированный конструктор.
вот.
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33484109
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ладно. ссылка на потомка это действительно странно хотя и реально :)
а вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
struct BASE
{
 BASE* parent;
 BASE(BASE* p)
 {
  parent=p;
 };
};

struct CHILD_A
{
 //bla bla bla
};

struct CHILD_B
{
 CHILD_A child_a;
};

CHILD_B child_b;
//вот строчку ниже делать не хочется
child_b.child_a.parent=&child_b;


вот у CHILD_B объект класса CHILD_A создасться конструктором по умолчанию.
и парент придется потом указывать в ручную.

а хочется чтобы парент автоматически указывался при создании.

это можно сделать в конструкторе CHILD_B.
и в принципе не проблема.
но если как-то можно по другому, то хотелось бы посмотреть :)
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33484154
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть такая вещь - список инициализации
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
class parent
{
public:
parent();
parent(int a);
};
class child: public parent
{
public:
   child(): parent( 10 ) {}
};
class child2
{
   parent prnt;
   int i;
public:
   child(): prnt( 10 ), i( 22 ) {}
};
и т.д.
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33484231
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кажется то что надо. спасибо.
как много я еще не знаю :)
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33484259
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
funikovyuriесть такая вещь - список инициализации


Парметр this (а как раз это надо, судя по первому сообщению) не рекомендуется использовать в списке инициализации. Хотя и не все компилеры выдают соотв. предупреждение.

Вот несколько надуманный, но не невероятный пример неприятных последствий. (а реально зависимости будут другими и менее очевидными) Дизайн коряв, и за такой код руки отрывать, конеш, но код компилируемый, а фантазии разработчиков бывают иногда и более извращенными :)

Код: 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.
#include <iostream>

using namespace std;

struct C2;
struct C1
{
    int m;
    C1(C2* parent);
};

struct C2 
{
    char *s;
    C1 child;

    C2(char *str);
};

/////////////////////////////////////////////////////////////////

C1::C1(C2* parent)
{
    cout << "psrent is : " << parent->s << endl;
}

C2::C2(char *str) : child(this)
{
    cout << "alloc\n";
    s = new char(strlen(str));
    strcpy(s, str);
}

int main()
{

    C2 c("test");
   
    return  0 ;
}
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33484780
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
redskin

Парметр this (а как раз это надо, судя по первому сообщению) не рекомендуется использовать в списке инициализации.

Полностью согласен. Объяснение этому очень простое - агрегированные объекты и базовые классы создаются раньше чем класс-потомок и передача им указателя this на самом деле означает передачу адреса еще не инициализированного объекта...
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485052
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
но если я просто сохраню this в переменной это будет нормально?

хотя в принципе угрозу понял. надо подумать еще, короче
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485257
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_kно если я просто сохраню this в переменной это будет нормально?

Совет дня типа...Если не знаете как сделать инструкциями языка тот или иной функционал - вспомните, что C++ это попытка формализации ОО. А ОО - это в общем-то жизнь...

Или по другому... Не корректно копаться в потрохах того, чего Вы не знаете (создано позже). Корректней сделать глагол и сказать - эй, кто там позже сделан - мне нужно твоё имя (к примеру). Сие можно (например) реализовать с помощью виртуальных методов.


с уважением
(круглый)
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485269
Бармолей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если ты хочешь избежать передачи указателя на неинициализированный объект, рассмотри возможность передачи в конструктор агрегируемогого объекта указателя на базовый класс.
Например, если есть некая конструкция типа
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
class A
{
public:
   int m_x;
   A() : m_x( 10 ) {}
};
class B
{
public:
   A* m_a;
   B(A* a) : m_a(a) {printf("%s", m_a->m_x);}
};
class AExt : public A
{
public:
    B m_b;
    AExt() : m_b(this) {}
};
где агрегируемый класс какбы спешит использовать то, куда он вложен, то всетаки будет все окей, потому что реально он использует базовый класс, который уже инициализирован.
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485327
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Бармалей
Код: plaintext
1.
2.
3.
4.
5.
6.
class B
{
public:
   A* m_a;
   B(A* a) : m_a(a) {printf("%s", m_a->m_x);}
};

а кто создает m_a?
что-то я недогоняю.
Ведь это просто указатель. На что он будет указывать при создании
m_b?
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485331
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бармолей

Не смешно... от того что вы передаете указатель на базовый класс ситуация только ухудшается - ведь класс так и не был создан до конца, а вы его кому-то передаете.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
class A
{
public:
   int m_x;
   A() : m_x( 10 ) {}

  virtual void f(void) =  0 ;
};
class B
{
public:
   A* m_a;
   B(A* a) : m_a(a) {printf("%s", m_a->m_x);}
};
class AExt : public A
{
public:
    B m_b;
    AExt() : m_b(this) , m_x( 20 ) {} // врядли то чего вы ожидаете :)

};
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485457
Бармолей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имеется ввиду что где то, ну в винмейн там или где угодно, есть код создания объекта класса AExt, например:
Код: plaintext
1.
AExt obj;
Последовательность вызова конструкторов будет тогда такой
1) A()
2) B()
3) AExt()
На этом и предлагается сыграть - что конструктор A уже отработал к моменту вызова конструктора B. Ситуация вовсе не ухудшается, если только агрегируемому объекту B достаточно иметь доступ к базовому классу а не к финальному. Поэтому я и написал - рассмотри возможность такой организации.
Поясняю. В строке
Код: plaintext
1.
AExt() : m_b(this) {}
объекту класса B передастся вовсе не Aext*, а A*, что следует из сигнатуры конструктора B. А конструктор A() уже вполне завершился, так что A* -указатель на совершенно валидный объект.

funikovyuri
Ожидаю что строка
Код: plaintext
1.
    AExt() : m_b(this) , m_x( 20 ) {} // врядли то чего вы ожидаете :)
не будет компилится, т.к. m_x не база и не мембер

ЗЫ
Очепятка: нужно конечно вместо %s писать %d\n
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485509
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Угу пример не удачный, пусть будет так
Код: 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.
#include <stdio.h>
class A
{
public:
   int m_x;
   A() : m_x( 10 ) {}
};
class B
{
public:
   A* m_a;
   B(A* a) : m_a(a) {printf("%d", m_a->m_x);}
};
class AExt : public A
{
public:
    B m_b;
    AExt() : m_b(this) { m_x= 20 ; }

};


void main(void)
{
  AExt aext;
}
объекту класса B передастся вовсе не Aext*, а A*, что следует из сигнатуры конструктора B. А конструктор A() уже вполне завершился, так что A* -указатель на совершенно валидный объект.

Идея в том, что у конструктра есть задача - перевести вновь созданный объект в некоторое начальное непротиворечивое состояние. Так вот с этой точки зрения передача указателя на объект у которого отработала только часть конструкторов - это только способ запутать логику работы коды... То что память там будет валидная - это и без базового конструктора будет верно так как выделение ее уже произошло
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485709
Бармолей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А что показывает второй пример? Можно еще хоть 100 раз после инициализации m_b указателем на A* поменять значение m_x и m_b, если его не дернуть, ничего не напечатает, что и следовало ожидать.

Идея в том, что у конструктра есть задача - перевести вновь созданный объект в некоторое начальное непротиворечивое состояние
Ну да. Оно и выходит непротеворечивым.

Так вот с этой точки зрения передача указателя на объект у которого отработала только часть конструкторов - это только способ запутать логику работы коды...
Субъективная оценка. Не, это способ ее добиться того, что все передаваемые указатели указывют на валидно сформированные объекты с отработанными конструкторами.
Вглядитесь в код и сравни с тем что ты говоришь, и увидишь, что слова твои неточны. Мы не передаем указатель на объект у которого отработала часть конструкторов. Мы передаем указатель не на AExt а на A, то есть на объект у которого все конструкторы отработали. A* и AExt*. Почувствуй разницу.
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485719
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
давно таких интересных тем небыло, аж душа радуется :)
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485736
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мы передаем указатель не на AExt а на A, то есть на объект у которого все конструкторы отработали. A* и AExt*. Почувствуй разницу.

А что, от того что ты объект типа AExt привел к указателю A* он вдруг стал объектом типа A у которого отработали все конструкторы? Интересное понимание полиморфизма ;)
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485831
Бармолей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
funikovyuriМы передаем указатель не на AExt а на A, то есть на объект у которого все конструкторы отработали. A* и AExt*. Почувствуй разницу.

А что, от того что ты объект типа AExt привел к указателю A* он вдруг стал объектом типа A у которого отработали все конструкторы? Интересное понимание полиморфизма ;)
Ну и дела. Понимаешь какая штука-то. Существует определенная последовательность вызова конструкторов. Сперва вызывается конструктор базового класса. Это сначала. В первую очередь (1). А потом конструкторы агрегированных объектов. Уже потом, понимаешь? Уже когда конструктор объекта A отработал. Это во вторую очередь (2). На шаге номер 2. И уже в самом конце вызывается конструктор класса AExt. Шаг 3 (3).
Вникаешь? Не оттого, что мы сделали приведение типов приключилось то, что конструктор A уже отработал. А потому, что A - базовый класс. Это важно. Прежде чем веселиться стоит об этом подумать. Вот оно как оказывается. Последовательность 1-2-3, см. выше. Эвона как.
И никаких абсурдов, которые ты присочинил и над которыми улыбаешься не произошло. AExt не стал объектом A, мы просто передали агрегируемому классу ссылку не на AExt, а на A. Он то остался классом AExt, но мы то передали ссылку на A. А у A и его предков конструкторы все отработали, когда мы эту ссылку передавали. Хотя у AExt конструктор конечно же не отработал еще, т.к. он идет на шаге 3, а объект типа B конструируется на шаге 2. Надеюсь, теперь понятнее, если нет - пардоньте :)
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485863
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бармолей

Существует определенная последовательность вызова конструкторов.

Я в курсе.

И никаких абсурдов, которые ты присочинил и над которыми улыбаешься не произошло.

Агрегированному конструктору можно передавать что-угодно, только объект ты создал типа AExt и его инициализация завершится только после того как отработает (кроме прочих) и его конструктор(AExt::AExt())... Не стоит думать о роли конструктора базового класса как о чем-то изолированном. Это уже не объект типа A - а нечто новое, в котором поведение базового конструктора может быть дополнено/переопределено в конструкторе производного класса. Последовательность вызова конструкторов строго определена и не может меняться - т.е. объект класса AExt будут в начальном состояние только после выполнения всей цепочки конструкторов, а не в ее середине. Кстати - как ты думаешь - зачем нужны виртуальные функции? Ведь по твоей логике если передал в агрегированный объект указатель на базывый класс достаточно чтобы вызывалась логика только базового класса :)

PS> ты зря пытаешься найти у меня пробелы в таких вещах как последовательность вызова конструкторов - лучше постарайся понять о чем я тебе пытаюсь рассказать
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485954
Бармолей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
funikovyuriКстати - как ты думаешь - зачем нужны виртуальные функции? Ведь по твоей логике если передал в агрегированный объект указатель на базывый класс достаточно чтобы вызывалась логика только базового класса :)
экзаменатор чтоли? ты прочти что написано, командир. я говорил Алексу_К :
я
рассмотри возможность передачи в конструктор агрегируемогого объекта указателя на базовый класс

Рассмотреть возможность - это значит обдумать, подходит ли в его случае решение.
ЗЫ
Твои пробелы или их отсутствие мне по барабану, я рассказывал Алексу_К возможный вариант решения, а ты чего-то о себе всё... Все ништяк, ты кульный чувак, нет у тебя пробелов, не переживай.
...
Рейтинг: 0 / 0
хитрое создание объектов в объекте
    #33485976
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бармолей

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


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