Каковы плюсы и минусы того, что источник обновления является ссылочным элементом, а не передается функциям обновления?

У меня есть класс, экземпляр которого полностью зависит от обновлений экземпляра отдельного класса. Упрощенный пример:

#include "Source.h"

class ObjectThatNeedsUpdates
{
public:
    ObjectThatNeedsUpdates();
    void update(const Source& source)
    {
        //Update member data with data from source
    }
private:
    //Some member data that needs updating
};

Как видите, каждый раз, когда я вызываю функцию обновления, я передаю константную ссылку класса Source. Но недавно я подумал, что, может быть, было бы логичнее передать ссылку на объект Source только один раз, когда создается ObjectThatNeedsUpdates, и позволить классу хранить ссылку как член, чтобы избежать необходимости передавать источник каждый раз, когда я хочу обновить объект.

Как таковой:

#include "Source.h"

class ObjectThatNeedsUpdates
{
public:
    ObjectThatNeedsUpdates(const Source& source)
      : source_(source)
    {
    }
    void update()
    {
        //Update member data with data from source_
    }
private:
    const Source& Source_;
    //Some member data that needs updating
};

Каковы плюсы и минусы этого подхода?

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

cigien 20.12.2020 22:32

Всякий раз, когда вы думаете об использовании ссылочного члена данных, вам почти всегда лучше использовать член данных указателя. Использование члена ссылочных данных отключает сгенерированное компилятором назначение, и часто невозможно правильно реализовать их самостоятельно. Аналогичные рассуждения применимы к использованию элементов данных const. Обычно лучше реализовать их как private не-const элементы данных и поддерживать инвариантность через интерфейс.

François Andrieux 20.12.2020 23:06

Ссылочный параметр может быть немного более элегантным с точки зрения внутренней инкапсуляции: это нужно только методу update()? - нет необходимости выставлять это как член для других методов. Не беспокойтесь об изменениях Source. Разница в производительности (по сравнению с членом) незначительна. В то время как, если вы занимаетесь shared_ptr, что дорого обходится, вы, в первую очередь, противоречите своей собственной мотивации...

bloody 21.12.2020 00:01

@bloody Я думал, что между указателями и ссылками почти нет разницы в производительности?

JensB 21.12.2020 18:24

@cigien Какой подход вы думаете? Может быть тот, который я представил в своем вопросе?

JensB 21.12.2020 18:29

Хорошо, может быть, я не совсем понял, о чем вы спрашивали. Виноват.

cigien 21.12.2020 21:32

@cigien Не беспокойтесь

JensB 25.12.2020 14:05
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
7
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Делайте то, что, по вашему мнению, лучше всего выражает контракт между вызывающей стороной update() и самим классом.

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

Хотя, подумайте о том, чтобы вместо этого держать std::shared_ptr. Это лучше защитит вас от жизненных проблем.

С точки зрения производительности передача ссылки в качестве аргумента функции чрезвычайно дешева (такая же стоимость, как передача указателя, что обычно равно стоимости передачи size_t).

Не думал о пожизненных проблемах, которые могут возникнуть. Спасибо, поменяю на shared_ptr

JensB 20.12.2020 23:00

Другие вопросы по теме