LINUX.ORG.RU

Общий базовый класс


0

1

Привет, есть такая ситуация.

class A {};
class B : public A {};
class C : public A {};

В какой-то момент, нужно синхронизировать данные между объектами класса B и С (т.е. те общие данные, что они имеют от класса A).

Что посоветуете в данном случае? Мне пока пришло в голову такое решение:

class B : public A
{
   C* c;
};

class C : public A
{
   B* b;
};
Явный недостаток в этом случае, что присутствуют 2 экземляра класса А.

★★★★★

Последнее исправление: UVV (всего исправлений: 1)

void A::Sync(A* a)
{
// sync logic there
}

?

k0l0b0k ★★
()
Ответ на: комментарий от vladimir-vg

Полиморфизм же!

А можно пояснить?

UVV ★★★★★
() автор топика

Что значит «синхронизировать»?

Может быть будет достаточно определить оператор присванивания в классе A (ну и в остальных тоже)? :)

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

Господи. ЧТо за страх

скажи, что надо

Я же написал, что надо. Или там непонятно написано?

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

Что значит синхронизовать? Зачем наследоваться, если данные?

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

я так понял что надо уметь копировать значения полей класса A в обоих направлениях (какие там наследники - не важно).
только operator= здесь не очень удобен будет.

k0l0b0k ★★
()

Если будет существовать два объекта, B и C, то данные, описанные в классе A, и так будут присутствовать в количестве двух штук.

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

Да, мне, например, тоже непонятно

Т.е. может быть просто неправильный дизайн... Как тогда сделать правильнее?

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

А. теперь кажется понял :)

Ну да, как тут уже сказал mv, если у нас будет два объекта классов B и С, данных класса А будет в количестве двух штук.

Так что я в этой ситуации заменил бы наследование на аггрегацию - чтобы в классах B и C были указатели на общий для них объект А.

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

typedef boost::shared_ptr<A> A_ptr;

class B { B(); A_ptr m_a; }

B::B() : m_a(new A) {}

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

Так что я в этой ситуации заменил бы наследование на аггрегацию - чтобы в классах B и C были указатели на общий для них объект А.

Да, но тогда я потеряю виртуальные методы.. (

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

Да, но тогда я потеряю виртуальные методы.. (

Сейчас скажите, что я о них ничего не говорил.. ))

UVV ★★★★★
() автор топика
Ответ на: комментарий от UVV
class A {};

class B
{
protected:
    A& mA;
public:
    B(A& pA)
        : mA(pA)
    {
    }
};

class C
{
protected:
    A& mA;
public:
    C(A& pA)
        : mA(pA)
    {
    }
};

вариантов масса. чтобы не хранить A на стороне, можно условно определить что B или C является владельцем объекта класса A, а другой класс - имеет мягкую ссылку на этот объект. как-то так.

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

Виртуальные методы, определённые в классе А? А они замкнуты вокруг состояния класса А?

Если да, то можно сделать опять же общий базовый класс + какой нибудь тупой POD для хранения данных (структуру или опять же класс). Базовый класс будет в конструкторе принимать (или сам аллоцировать) расшаренный объект.

Это один из вариантов, который сразу пришёл в голову :)

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

s/состояния класса/состояния экземпляра класса А/

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

Если да, то можно сделать опять же общий базовый класс + какой нибудь тупой POD для хранения данных (структуру или опять же класс). Базовый класс будет в конструкторе принимать (или сам аллоцировать) расшаренный объект.


Мысль понял, спасибо. Только что такое POD? =)

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

Почему выкрутасы? Синтаксически это выглядит может чуть страшно, но это C++. А по факту это имхо наиболее безопасный способ выполнить то, что нужно, при условии что классы B или C - знают, что делают, и если у них есть какие-то данные зависимые от содержимого A, то они сами это обновят, с другой стороны - ни B ни C в данном случае не должны задумываться о том, что внутри у A, равно как и задумываться об корректном копировании его данных - этим пусть занимается сам «A».

В чем проблема?

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

> Для подстраховки :) понятное дело, что тут в принципе в compile time все верефицируется

а кто bad_cast ловить будет? Зачем в динамике? статическую типизацию отменили?

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

касты чаще зло чем не зло, композиция уместнее

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