Действительно ли это - хорошая практика для передачи объекта структуры как параметра к функции в C++?

Я попробовал пример, живой ниже:

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

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

8
задан qwr 17 May 2016 в 15:26
поделиться

6 ответов

Нет ничего плохого в передаче структур в качестве параметров. В 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
}
8
ответ дан 5 December 2019 в 05:25
поделиться
void cp(point p){
}

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

void cp(point *p){
}

получает его по ссылке

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

В java сценарий другой. Передаваемые объекты всегда идут по ссылке.

0
ответ дан 5 December 2019 в 05:25
поделиться

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

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

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

или в качестве константной ссылки

void cp(const point& p) // p may not be altered!
0
ответ дан 5 December 2019 в 05:25
поделиться

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

void cp(const point& p)
{
    // ...
}
18
ответ дан 5 December 2019 в 05:25
поделиться

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


1. Объекты, созданные копированием (передача по значению):

void cp(point p);

Это передача по значению. Временный объект point создается и копируется из любого объекта point , который вы передаете в cp . Как только выполнение покидает функцию cp , временный объект уничтожается.

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


2. Ссылки на объекты (передача по ссылке):

void cp(point& p);

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

void cp(const point& p);

3. Указатели на объекты (передача по ссылке):

void cp(point* p);

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

void cp(const point* p);

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

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

5
ответ дан 5 December 2019 в 05:25
поделиться

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

void cp (point & p const) const {

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

}

0
ответ дан 5 December 2019 в 05:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: