почему конструктор копирования вызывается, когда мы передаем объект в качестве аргумента по значению методу

Я новичок в программировании на C ++. Когда я делаю некоторые программы на C ++, у меня возникает сомнение, поэтому конструктор копирования вызывается, когда я передаю объект в качестве аргумента по значению функции. пожалуйста, смотрите мой код ниже, в котором я передаю объект класса в качестве аргумента по значению в функцию display (), но он вызывает конструктор копирования, а затем элемент управления выполняет функцию display (), но я понимаю, почему это так, пожалуйста, помогите.

#include "stdafx.h"#include <iostream>
using namespace std;

class ClassA
{
private:
int a, b;
public:
ClassA()
{
a = 10, b = 20;
}
ClassA(ClassA &obj)
{
cout << "copy constructor called" << endl;
a = obj.a;
b = obj.b;
}
};
void display(ClassA obj)
{
cout << "Hello World" << endl;
}
int main()
{
ClassA obj;
display(obj);
return 0;
}

8

Решение

Для уточнения двух ответов уже дано немного:

Когда вы определяете переменные как «совпадающие» с некоторой другой переменной, у вас есть две возможности:

ClassA aCopy = someOtherA; //copy
ClassA& aRef = someOtherA; //reference

Вместо неконстантных lvalue-ссылок, конечно же, есть const-ссылки и rvalue-ссылки. Главное, на что я хочу обратить внимание: aCopy не зависит от someOtherA, в то время как aRef практически такая же переменная, как someOtherAэто просто другое имя (псевдоним) для него.

С параметрами функции это в основном то же самое. Когда параметр является ссылкой, он связывается с аргументом при вызове функции, и это просто псевдоним этого аргумента. Это означает, что вы делаете с параметром, вы делаете с аргументом:

void f(int& iRef) {
++iRef;
}

int main() {
int i = 5;
f(i); //i becomes 6, because iRef IS i
}

Когда параметр является значением, он является только копией аргумента, поэтому независимо от того, что вы делаете с параметром, аргумент остается неизменным.

void f(int iCopy) {
++iCopy;
}

int main() {
int i = 5;
f(i); //i remains 5, because iCopy IS NOT i
}

Когда вы передаете по значению, параметр является новым объектом. Должно быть, так как это не то же самое, что аргумент, он независим. Создание нового объекта, который является копией аргумента, означает вызов конструктора копирования или конструктора перемещения, в зависимости от того, является ли аргумент lvalue или rvalue.
В вашем случае, передача функции по значению не нужна, потому что вы только читаете аргумент.

Eсть Руководство от ПОЛУЧИЛО № 4:

Предпочитают передавать параметр только для чтения по const& если вы только собираетесь читать из него (не делайте его копию).

11

Другие решения

Поскольку передача значения в функцию означает, что функция имеет собственная копия объекта. Для этого вызывается конструктор копирования.

void display(ClassA obj)
{
// display has its own ClassA object, a copy of the input
cout << "Hello World" << endl;
}

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

4

Как сказал juanchopanza, вы передаете по значению, что приводит к созданию копии. Если вы хотите предотвратить это, вы можете перейти по ссылке:

void display(const ClassA &obj)

О sidenote: Вы должны объявить свой экземпляр ctor, чтобы принимать аргумент как константную ссылку:

ClassA(const ClassA &obj)

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

2
По вопросам рекламы [email protected]