LINUX.ORG.RU

C++: Совместное использование объекта


0

1

Есть классы - A, B, C. Необходимо использовать указатель на объект C в A и B. Объект C должен быть один и тот же в A и B.

Сделал примерно следующее:

A::A() {

   c = new C;
   b = new B(c);
};

class B {

  C *bc; 
};

B::B(C *cc) {

   bc = cc;
}

B::method() {
   bc->...       // использование
}

Нужно ли в этом случае для C перегружать операцию присваивания (и как) ? И есть ли решение покрасивше ?


class A;
class B;
class C;

C* c = new C();
A* a = new A(c);
B* b = new B(c);
andreyu ★★★★★
()
Ответ на: комментарий от shty

Указатель на объект класса C нужно использовать в объектах A, B. Объект С должен быть одним и тем же (не копия) для А и В. Создаваться объект C должен в А. Вопрос: как лучше (правильнее) передать его в В ?

drZlo
() автор топика
Ответ на: комментарий от drZlo

Указатель на объект класса C [..] Вопрос: как лучше (правильнее) передать его в В ?

как показывает практика, наиболее подходящим способом передать указатель в функцию является передача указателя

да сам указатель будет скопирован при передаче в функцию, но он будет указывать на тот объект который нужно

для конструктора класса 'B' Вы всё практически правильно сделали

shty ★★★★★
()
Ответ на: комментарий от Yareg

Да, вроде нет ) Просто может узкие места какие ? И присваивание как-нить для надежности перегрузить в C ?

drZlo
() автор топика
Ответ на: комментарий от drZlo

Да, вроде нет ) Просто может узкие места какие ? И присваивание как-нить для надежности перегрузить в C ?

тут можно только проверить что передали не NULL

и внимательно смотреть чтобы не сделетить объект где в деструкторе (или ещё где)

вроде всё

shty ★★★★★
()
Ответ на: комментарий от drZlo

Хотя вообще хороший вариант — не хранить голые указатели, а использовать shared_ptr с подсчётом ссылок.

Yareg ★★★
()
Ответ на: комментарий от Yareg

Хотя вообще хороший вариант — не хранить голые указатели, а использовать shared_ptr с подсчётом ссылок.

с точки зрения хранения указателя в классе - никакой разницы

shty ★★★★★
()
Ответ на: комментарий от shty

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

Yareg ★★★
()
Ответ на: комментарий от Yareg

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

не, это да, но это уже перестраховка, имхо

shty ★★★★★
()
Ответ на: комментарий от shty

Ну от задачи зависит, да. Если как у ТС в первом посте b агрегирован в a, то a может быть ответственен за всё, потому что он всяко умрёт после b. А если это два несвязанных объекта, то лучше уж перестраховаться.

Yareg ★★★
()

Я бы рекомендовал посмотреть в сторону смартпоинтеров.
Лучше же пересмотреть архитектуру: замкнуть C в B, а со стороны A доступ к C обеспечить через интерфейсы B.

trex6 ★★★★★
()

Простите, что вмешиваюсь, но кто будет гарантировать нужный порядок освобождения пары объектов A и B? И каким способом будет эта парность поддерживаться?

gpg
()
Ответ на: комментарий от yoghurt

А вот господин shty говорит, что он не нужен. Да и как он защитит от использования одного и того же C в более чем двух экземплярах A и B?

gpg
()
Ответ на: комментарий от gpg

Собственно, хотел лишь указать на единственное здравое предложение от trex6. Если я правильно понял ТС.

gpg
()
Ответ на: комментарий от drZlo

Просто может узкие места какие ?

Если уж трястись над каждым байтом, то для избежания копирования указателя можно передавать его по ссылке:

void fit_func(Pointer*& pointer)
{
 ...
}

one_more_hokum ★★★
()
Ответ на: комментарий от one_more_hokum

>Если уж трястись над каждым байтом, то для избежания копирования указателя можно передавать его по ссылке:

WUT? Омич или тролль?

Yareg ★★★
()
Ответ на: комментарий от Yareg

Среднестатистический лоровец. Не обижай омичей.

gpg
()
Ответ на: комментарий от one_more_hokum

Как может передача по ссылке сэкономить байты? Ведь компилируется ссылка в тот же самый указатель, только константный. В итоге имеем двойное разыменование вместо одинарного, т.е. вообще ничего не выигрываем в памяти, но ещё и теряем в тактах.

Yareg ★★★
()
Ответ на: комментарий от one_more_hokum
int a(int*& a)
{
  int b = *a;
  return b;
}

-O1

_Z1aRPi:
.LFB0:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        movl    %esp, %ebp
        .cfi_offset 5, -8
        .cfi_def_cfa_register 5
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        movl    (%eax), %eax
        popl    %ebp
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
Yareg ★★★
()
Ответ на: комментарий от one_more_hokum

А как ещё по другому она может себя вести? Мы в любом случае должны передать что-то в функцию: либо сам наш указатель, либо указатель на него. Не через астрал же.

Yareg ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.