Шаблон указателя ссылки - общее использование? - PullRequest
1 голос
/ 09 июля 2011

В системе, в которой текущий объект управляется другими содержащимися объектами, при передаче ссылки на текущий объект создается впечатление, что ссылка продолжается и продолжается .... без какого-либо конца (Для приведенного ниже кода, Car->myCurrentComponent->myCar_Brake->myCurrentComponent->myCar_Brake->myCurrentComponent....).

I Car и Car->myCurrentComponent->myCar_Brake относятся к одному и тому же адресу, указывают на одинаковые объекты.Это как Автомобиль содержит Тормоз, который относится к Автомобилю.

Фактически, Car является единственным объектом, myCar_Brake и myCar_Speed ​​просто ссылаются на него (указывают). Является ли этот вид использования ссылки и указателя нормальным?Есть ли потенциальные проблемы с этим подходом?

Пример кода

class Brake
class C

class   Car
{

public:

Car();
// Objects of type B and C.
Brake*  myBrake;
Speed*  mySpeed;

// Current component under action.

Component*  myCurrentComponent;

}
/******************************/
// Constructor

Car::Car()
{
myBrake = new Brake(*this);
mySpeed = new Speed(*this);

myCurrentComponent = myBrake;
}

/******************************/
class   Brake: public   Component
{

public:

Brake(Car&);
// Needs to operate on A.
Car*    myCar_Brake;

}

// Constructor
Brake::Brake(Car&)
{
myCar_Brake = Car;
}

/******************************/
class Speed
{

public:

Speed(Car&);

// Needs to operate on A.
Car*    myCar_Speed;

}

// Constructor
Speed::Speed(Car&)
{
myCar_Speed = Car;
}

/****************************/

Ответы [ 3 ]

5 голосов
/ 09 июля 2011

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

0 голосов
/ 20 июня 2016

Без обсуждения достоверности фактической структуры объекта отношения Car, Break и Speed, этот подход имеет одну незначительную проблему: он может быть в недопустимых состояниях.

Если -что-то идет не так, возможно в этой настройке, что Car экземпляр # 1 имеет Break экземпляр # 2, который принадлежит Car экземпляру # 3.Общая проблема с двусвязными списками - сама архитектура допускает недопустимые состояния.Конечно, тщательный выбор модификатора видимости и хорошая реализация функций могут гарантировать, что этого не произойдет.И когда это будет сделано и безопасно, вы перестанете изменять его, возьмете его в качестве «черного ящика» и просто используете его, таким образом исключая вероятность его облажания.

Но я лично рекомендую избегатьархитектуры, которые допускают недопустимые состояния для высокого уровня, постоянно поддерживаемый код.Двусвязный список - это код низкого уровня, который, скорее всего, не потребует никаких изменений кода, как никогда.Можете ли вы сказать, что о ваших Car, Break и Speed?

Если бы у Car были Break и Speed, а Break и Speed не знали быиз их "владения Car", было бы невозможно сделать и недействительным состояние.Конечно, это может не подходить к конкретной ситуации.

0 голосов
/ 09 июля 2011

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

Есть ли смысл разрешать что-то подобное?

Speed::Speed(Car& value)
{
  myCar_Speed = value;
  // WTF code below
  value->myCurrentComponent->myCar_Brake = NULL;
}

Кроме того,

Car::Car()
{
  myBrake = new Brake(*this);
  mySpeed = new Speed(*this);
  //if Speed::Speed(Car&) throws an exception, memory allocated for myBrake will leak
  myCurrentComponent = myBrake;
}

Никогда не используйте необработанные указатели без какого-либо менеджера ресурсов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...