Является ли хорошей практикой для передачи объекта Struct AS в качестве параметра к функции в C ++?

StackOverflow https://stackoverflow.com/questions/2724708

  •  02-10-2019
  •  | 
  •  

Вопрос

Я попробовал пример жить ниже:

typedef struct point
{
    int x;
    int y;
} point;

void cp(point p)
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
}

Результат, который напечатан:

1
2

который я ожидал. Мой вопрос: PARAMETER P получает полную копию объекта P1? Если это так, интересно ли это хорошая практика? (Я предполагал, что по размеру структуру стало большим, это создаст много копий накладных расходов).

Это было полезно?

Решение

Нет ничего плохого в прохождении структур в качестве параметров. Все пройдено по значению в C ++, поэтому полная копия действительно сделана.

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

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

Ваш пример может быть изменен для работы с ссылками таким образом:

typedef struct point
{
    int x;
    int y;
} point;

void cp(const point& p) // You can know that cp doesn't modify your struct
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

void mod_point(point& p) // You can know that mod_points modifies your struct
{
    p.x += 1;
    p.y += 1;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
    mod_point(p1);
    cp(p1); // will output 2 and 3
}

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

Да, в этом нет ничего плохого и да, p является полной копией p1. Отказ Я бы не назвал struct с двумя intбольшой, но если struct Ставьте большие и если вам не нужно изменять его в функциональном теле, вы могли бы рассмотреть возможность передачи его Const Refect:

void cp(const point& p)
{
    // ...
}

Прежде чем я даю ответ на ваш вопрос (Вы найдете его в конце этого поста), вот краткое резюме возможностей, которые вы имеете для передачи аргументов в функцию:


1. Копирование, построенные объекты (pass-by-value):

void cp(point p);

Это по почте. Временный point Объект создан и скопирован, построенный из чего point объект, в который вы переходите в cp. Отказ После того, как исполнение оставляет cp Функция, временный объект разрушен.

Обратите внимание, что, поскольку функция работает на копии того, что было передано на функцию, вы можете изменить этот локальный point Объект столько, сколько вы хотите, исходный объект абонента не будет затронут. Нет никаких способов изменить это поведение с параметрами Pass-Value.


2. Ссылки на объекты (Pass-by-Revource):

void cp(point& p);

Это справочная передача. Фактический объект, переданный на функцию, доступен (и потенциально подлежит модификации) внутри функции. Если вы не хотите, чтобы функция была возможность изменить пропущенную объект, объявить параметр как const point&:

void cp(const point& p);

3. Указатели на объекты (Pass-by-Reference):

void cp(point* p);

Это также передается с помощью нескольких тонких различий. Одно известное разница состоит в том, что вы можете передавать нулевой указатель на функцию. Это невозможно с ссылками, потому что ссылки должен быть инициализированным и нельзя заранее перепрашивать. - как с ссылками, если вы хотите запретить cp от изменения прохожденного point, Объявите его как const:

void cp(const point* p);

Ответ на ваш вопрос:

Параметры Pass-Value не по своей природе неплохо не плохо. Конечно, есть типы, для которых копирование строительство дороги (например, очень большие или сложные объекты), или где он имеет определенные побочные эффекты (например, с std::auto_ptr). В этих случаях вы должны быть осторожны. В противном случае это просто еще одна особенность C ++, которая имеет свое совершенно разумное использование.

void cp(point p){
}

Получает это по значению

void cp(point *p){
}

Получает это посредством ссылки

Как и любая другая переменная данных.

В Java сценарий отличается. Проходящие объекты всегда проходят посредством ссылки.

В вашем случае точечная структура пропускается «значением», что означает, что вся структура копируется. Для больших типов данных это действительно может быть медленным.

Вы можете рассмотреть возможность передачи объекта посредством ссылки

void cp(point& p) // p may be altered!

или быть константом

void cp(const point& p) // p may not be altered!

Смотрите возможности, чтобы избежать прохождения объектов по значению. Объект не просто «скопирован», но является скопированным. Итак, это включает в себя вызов Copy Constructor и цепочку конструкторов копирования, если ваш объект создан или получен из большего количества объектов. Пройти по ссылке, если это возможно.

void cp (point & p const) const {

    cout << p.x << endl;
    cout << p.y << endl;

}

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top