Я новичок в программировании на 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;
}
Для уточнения двух ответов уже дано немного:
Когда вы определяете переменные как «совпадающие» с некоторой другой переменной, у вас есть две возможности:
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& если вы только собираетесь читать из него (не делайте его копию).
Поскольку передача значения в функцию означает, что функция имеет собственная копия объекта. Для этого вызывается конструктор копирования.
void display(ClassA obj)
{
// display has its own ClassA object, a copy of the input
cout << "Hello World" << endl;
}
Имейте в виду, что в некоторых случаях копии могут быть исключены, например, если в функцию передано временное значение.
Как сказал juanchopanza, вы передаете по значению, что приводит к созданию копии. Если вы хотите предотвратить это, вы можете перейти по ссылке:
void display(const ClassA &obj)
О sidenote: Вы должны объявить свой экземпляр ctor, чтобы принимать аргумент как константную ссылку:
ClassA(const ClassA &obj)
В противном случае вы не сможете использовать копию ctor для именованных объектов, помеченных как const или с временными файлами. Это также предотвращает случайное изменение переданного объекта.