Это хорошая практика для передачи объекта структуры в качестве параметра функции в 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? Если так, то мне интересно, если это хорошая практика? (Я предполагал, что когда структура станет больше по размеру, это приведет к большим затратам на копирование).

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
}

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

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

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


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 от изменения переданного в point, объявите это как const:

void cp(const point* p);

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

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

void cp(point p){
}

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

void cp(point *p){
}

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

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

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

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

void cp (point & p const) const {

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

}

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

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

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

или быть постоянной ссылкой

void cp(const point& p) // p may not be altered!
Другие вопросы по тегам