Пересылка объекта в C++

Я работаю над проектом с ESP32 и MCP23017.

В основной программе я создаю объект для MCP и инициализирую адрес.

Adafruit_MCP23X17 pin_Expander;
const int expander_addr = 0x20; // Adress 0x20 

void setup()
{
    Serial.begin(9600);

    pin_Expander.begin_I2C(expander_addr);
    expander_Init(pin_Expander);
}

Поскольку я использую в проекте много операций ввода-вывода, я хотел передать их инициализацию на аутсорсинг и написал функцию. Я создал отдельный заголовочный файл для функции.

void expander_Init(Adafruit_MCP23X17 pin_Expander)
{
    // Load the GPIOs
    pin_Expander.pinMode(pin1_Motor1, OUTPUT); // I have removed the other pins

    // Set all GPIOs to LOW
    pin_Expander.digitalWrite(pin1_Motor1, LOW); // I have removed the other pins
}

Интересно, это законный способ передать объект в другую функцию?

Вы передаете по значению, так что это, вероятно, неверно.

ChrisMM 04.01.2023 18:11

Вам нужно expander_Init принять по ссылке (Adafruit_MCP23X17 & pin_Expander), если вы хотите, чтобы он влиял на экземпляр, переданный ему из main.

wohlstad 04.01.2023 18:16

Правильно это или нет, зависит от объекта Adafruit. Передача по значению означает копирование объекта! Это может быть просто прекрасно (небольшой объект не должен быть изменен в любом случае или если изменение внутри функции нормально, в то время как исходный объект должен оставаться неизмененным), это может быть дорогостоящей операцией, но в остальном хорошо (если объект большой или требует динамического выделения памяти , иначе как раньше), и это может пойти совершенно неправильно (если исходному объекту нужно каким-либо образом изменить свое состояние) - к сожалению, последнее является наиболее распространенным случаем...

Aconcagua 04.01.2023 18:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Adafruit_MCP23X17 — это класс C++ , а не какое-то определение типа, которое имитирует семантику ссылок в C, поэтому, когда вы объявляете свою функцию:

void expander_Init(Adafruit_MCP23X17 pin_Expander)

вы принимаете объект по значению, а не по ссылке, что означает expander_Init(pin_Expander); копирование pin_Expander и передачу копии. Любые изменения в копии обычно не влияют на исходную версию (если только класс плохо спроектирован†).

Если вы хотите изменить исходную версию, измените прототип на:

void expander_Init(Adafruit_MCP23X17& pin_Expander)
                                 // ^ added & to make it accept by reference

это означает, что вы примете ссылку на то, что передал вызывающий объект, без каких-либо копий, и все, что вы делаете с этой ссылкой, эквивалентно выполнению этого с исходным переданным вызывающим объектом.


† Отмечу: я не удивлюсь, если класс будет плохо спроектирован, а все методы экземпляра эффективно модифицируют глобальное, а не отдельное состояние экземпляра (низкоуровневые аппаратные манипуляции часто могут делать подобные предположения), так что ваш первоначальный код может работать просто отлично, но это не гарантируется без проверки исходного кода, и это может привести к некоторой неэффективности дополнительной работы по копированию и уничтожению, которой избегает передача по ссылке.

Спасибо. Сегодня я смог протестировать ваше решение. Теперь все работает нормально.

Teebow 07.01.2023 15:15

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