Я не понимаю разницы между передачей экземпляра объекта и передачей разыменованного объекта. я имею
class A
{
public:
A() {}
void m() {}
};
void method(A& a)
{
a.m();
}
int main(int argc,char** argv)
{
method(A());
return 0;
}
Вызов выше не работает с ошибками компилятора:
In function 'int main(int, char**)':
error:no matching function for call to 'method(A)'
note: candidates are:
note: void method(A&)
note: no known conversion for argument 1 from 'A' to 'A&'
note: void method(B&)
no known conversion for argument 1 from 'A' to 'B&'
Но если я напишу
method(*(new A()));
оно делает.
Может кто-нибудь сказать, пожалуйста, почему и как решить проблему, если я не могу изменить метод, который хочу вызвать?
Здесь вы создаете временный объект:
method(A()); // A() here is creating a temporary
// ie an un-named object
Вы можете получить только const&
к временным объектам.
Итак, у вас есть два варианта:
Так:
// Option 1: Change the interface
void method(A const& a) // You can have a const
// reference to a temporary or
// a normal object.// Options 2: Pass a real object
A a;
method(a); // a is an object.
// So you can have a reference to it.
// so it should work normally.
В первом случае вы создаете временный объект, который вы пытаетесь передать method
,
Временный объект не может быть изменен (его не имеет смысла изменять, он исчезнет в тот момент, method
возвращается). Таким образом, чтобы передать временное по ссылке, вы должны пройти мимо постоянная ссылка.
void method(const A& a)
{
}
Если бы это было законно, случались бы ужасные вещи. Рассматривать:
void addOne(double& j) { ++j; }
int q = 10;
addOne(q);
Это создаст временный double
, добавьте один к нему, и оставьте свой оригинал q
неизмененной. Уч.
Если method
изменяет свой параметр, ваш код не работает. Если это не так, это должно занять const
ссылка.
Проблема, которую вы видите, состоит в том, что ваша функция принимает только lvalue типа A. Чтобы решить эту проблему, вы можете либо изменить свою функцию, чтобы она принимала тип A по значению:
void method( A a ) {}
или по ссылке:
void method( const A &a ) {}
или по ссылке rvalue (если вы используете C ++ 11):
void method( A &&a ) {}
или передайте lvalue типа A вашему методу:
A a; method( a );
Если вы хотите понять проблему глубже, прочитайте о именующий в с ++