typedef boost::shared_ptr<class A> APtr;
class A
{
int a;
};
typedef boost::shared_ptr<class B> BPtr;
class B
{
int b;
APtr a;
};
typedef boost::shared_ptr<class C> CPtr;
class C
{
int c;
A a;
};
Вопросы в следующем:
1. Если я создам объект класса APtr, то он создается в куче и, по идее, его атрибут — а — тоже должен быть в куче — правильно?
2. Если я создам объект класса BPtr, то он также создается в куче, но у него есть атрибут — b — который отдельно создается в куче — и они все в куче — правильно ?
3. Ну и создаю я объект класса CPtr — он так же в куче, но он содержит объект класса А, который вроде как стековый — или он все равно в куче как часть объекта CPtr?
4. Ну и исходя из вопросов 2 и 3 — какая практика лучше — создавать объекты клаcс BPtr или CPtr, или, скорее, в каком случае какая практика лучше?
Здравствуйте, R1K0, Вы писали:
RK>Вопросы в следующем: RK>1. Если я создам объект класса APtr, то он создается в куче и, по идее, его атрибут — а — тоже должен быть в куче — правильно?
— У APtr нет аттрибута a, у него есть какойнить приватный A * m_ptr, который указывает на объект A, размещенный на куче, у которого как раз и есть аттрибут a
объект класса APtr скорее всего будет создан на стеке, ибо нормальное его использование:
APtr smartPointerToClassA = make_shared<A>();
а не
APtr * smartPointerToClassA = new APtr( make_shared<a>() );
RK>2. Если я создам объект класса BPtr, то он также создается в куче, но у него есть атрибут — b — который отдельно создается в куче — и они все в куче — правильно ?
с учетом предыдущего:
объект BPtr создается на стеке, в нем есть указатель, адресующий объект B, созданный в отдельном куске на куче, и содержащий int B::b и B::APtr. B::APtr в свою очередь имеет указатель, адресущий объект A, созданный в каком-то другом куске кучи (и содержаший A::a) RK>3. Ну и создаю я объект класса CPtr — он так же в куче, но он содержит объект класса А, который вроде как стековый — или он все равно в куче как часть объекта CPtr?
На стеке будет создан CPtr, у которого есть указатель, который адресует обект C, созданный на куче и содержаший в себе c и A (который в свою очередь содержит в себе A::a) RK>4. Ну и исходя из вопросов 2 и 3 — какая практика лучше — создавать объекты клаcс BPtr или CPtr, или, скорее, в каком случае какая практика лучше?
С точки зрения архитектуры — надо смотреть конкретную архитектуру.
С точки зрения производительности:
— если у тебя их не мульены — без разницы (ну, вариант 3 может быть более дружественен к кешу, но если не мульены — то и пофиг)
— если у тебя их мульены — все варианты — какашка, нужно переделывать под контейнеры и, в зависимости от процесса обработки данных может быть выгоден как вариант 2, так и 3.
ps/
наврал про мульены и без разницы:
— если у тебя 1 объект к которому очень много обращений, то вариант 3 опять будет быстрей, так-как меньше разыменований.
RK> какая практика лучше...
Лучше:
а. Разобраться с обычными указателями и ручным управлением памятью прежде чем изучать автоматические.
б. Избегать shared_ptr как огня.
ps/
все, на самом деле очень просто (статических членов опускаем)
1. члены объекта класса создаются там же, где и сам объект.
2. если создание объекта делается через new/make_shared — он будет создан на куче.
3. если создание объекта делается через объявление — он будет создаен на стеке, за исключением пункта 1.
Здравствуйте, Vamp, Вы писали:
V>Лучше: V>а. Разобраться с обычными указателями и ручным управлением памятью прежде чем изучать автоматические.
+1 V>б. Избегать shared_ptr как огня.
Только сначала разобраться почему, и когда не надо избегать
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, R1K0, Вы писали:
RK>Всем привет. Вот есть у меня некий набор классов: RK>
RK>typedef boost::shared_ptr<class A> APtr;
RK>class A
RK>{
RK> int a;
RK>};
RK>typedef boost::shared_ptr<class B> BPtr;
RK>class B
RK>{
RK> int b;
RK> APtr a;
RK>};
RK>typedef boost::shared_ptr<class C> CPtr;
RK>class C
RK>{
RK> int c;
RK> A a;
RK>};
RK>
RK>Вопросы в следующем: RK>1. Если я создам объект класса APtr, то он создается в куче и, по идее, его атрибут — а — тоже должен быть в куче — правильно?
Нет. У APtr нет члена a. Если вы просто создадите объект класса APtr, то объект типа А создан не будет:
APtr p;
— никакого объекта в куче не создаётся. Никакого объекта класса A не создаётся. Объект p класса (типа) APtr лежит на стеке и указывает в никуда.
Однако, если создать в куче объект класса A и инициализировать объект класса APtr указателем на этот созданный объект:
APtr p(new A);
, то объект p класса (типа) APtr лежит на стеке и указывает на объект класса (типа) А, который расположен в куче и который включает в себя атрибут (поле) a.
RK>2. Если я создам объект класса BPtr, то он также создается в куче, но у него есть атрибут — b — который отдельно создается в куче — и они все в куче — правильно ?
Нет. У BPtr нет члена b. Если вы просто создадите объект класса BPtr, то объект типа А создан не будет (так же как и объект класса B):
BPtr p;
— никакого объекта в куче не создаётся. Никакого объекта класса B не создаётся. Объект p класса (типа) BPtr лежит на стеке и указывает в никуда.
Однако, если создать в куче объект класса B и инициализировать объект класса BPtr указателем на этот созданный объект:
BPtr p(new B);
, то объект p класса (типа) BPtr лежит на стеке и указывает на объект класса (типа) B, который расположен в куче и который включает в себя два атрибута (поля), которые лежат в куче. При этом поле а объекта b указывает в никуда.
RK>3. Ну и создаю я объект класса CPtr — он так же в куче, но он содержит объект класса А, который вроде как стековый — или он все равно в куче как часть объекта CPtr?
Нет. CPtr не содержит объект класса А. Если вы просто создадите объект класса СPtr, то объект типа А создан не будет (так же как и объект класса C):
CPtr p;
— никакого объекта в куче не создаётся. Никакого объекта класса A не создаётся. Никакого объекта класса C не создаётся. Объект p класса (типа) CPtr лежит на стеке и указывает в никуда.
Однако, если создать в куче объект класса C и инициализировать объект класса CPtr указателем на этот созданный объект:
CPtr p(new C);
, то объект p класса (типа) CPtr лежит на стеке и указывает на объект класса (типа) C, который расположен в куче и который включает в себя атрибут (поле) a класса (типа) А, а так же атрибут (поле) c класса (типа) int.
RK>4. Ну и исходя из вопросов 2 и 3 — какая практика лучше — создавать объекты клаcс BPtr или CPtr, или, скорее, в каком случае какая практика лучше?
Для разных целей используются разные структуры.
Здравствуйте, R1K0, Вы писали:
RK>Я видимо не совсем правильно спросил — я прекрасно знаю как работать с умными и значем про new — вопрос именно в том как в памяти располагается и все.
Напишите создание объектов, как вы его видите, а я тогда смогу нарисовать, как они условно будут лежать.