Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / хитрое создание объектов в объекте / 25 сообщений из 27, страница 1 из 2
13.01.2006, 05:39
    #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
13.01.2006, 08:17
    #33480377
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
по мне главное что бы решение было эффективно, а красивости ф топку
...
Рейтинг: 0 / 0
13.01.2006, 08:18
    #33480381
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
эффективность один из компонентов красоты :)
...
Рейтинг: 0 / 0
15.01.2006, 15:17
    #33483536
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
Первый вариант прокатит. Только я не понял второго куска -


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

- это невалидный код.
...
Рейтинг: 0 / 0
15.01.2006, 17:25
    #33483665
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
чего сделать то пытаетесь? А то ссылка на потомка в базовом классе - это как-то странно выглядет :)
...
Рейтинг: 0 / 0
16.01.2006, 09:06
    #33484099
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
я хочу чтобы при создании PARENT автоматически создавался объект CHILD
но это возможно только с конструктором по умолчанию.
а мне хочется чтобы автоматически вызывался параметризированный конструктор.
вот.
...
Рейтинг: 0 / 0
16.01.2006, 09:12
    #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
16.01.2006, 09:43
    #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
16.01.2006, 10:20
    #33484231
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
кажется то что надо. спасибо.
как много я еще не знаю :)
...
Рейтинг: 0 / 0
16.01.2006, 10:36
    #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
16.01.2006, 13:14
    #33484780
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
redskin

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

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

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

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

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


с уважением
(круглый)
...
Рейтинг: 0 / 0
16.01.2006, 15:14
    #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
16.01.2006, 15:30
    #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
16.01.2006, 15:31
    #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
16.01.2006, 16:15
    #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
16.01.2006, 16:42
    #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
16.01.2006, 18:08
    #33485709
Бармолей
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
А что показывает второй пример? Можно еще хоть 100 раз после инициализации m_b указателем на A* поменять значение m_x и m_b, если его не дернуть, ничего не напечатает, что и следовало ожидать.

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

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

А что, от того что ты объект типа AExt привел к указателю A* он вдруг стал объектом типа A у которого отработали все конструкторы? Интересное понимание полиморфизма ;)
...
Рейтинг: 0 / 0
16.01.2006, 19:04
    #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
16.01.2006, 19:21
    #33485863
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
хитрое создание объектов в объекте
Бармолей

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

Я в курсе.

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

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

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

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

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


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