Как передать объект класса по ссылке?
Весь вопрос в шапке, но продублирую: Как передать объект класса по ссылке?
![]()
Передача объекта по ссылке используется достаточно часто и описана во многих книгах по С++, однако не всем получается быстро понять данный механизм.
Для начала рассмотрим принимающую сторону, т.е. функцию или метод класса, в который передается ссылка на объект. В простейшем случае это выглядит так:
К типу передаваемого объекта добавляется символ & , причем его можно размещать как вплотную к типу, так и к имени объекта. Это зависит от стиля программирования.
При передачи объекта по ссылке не происходит копирования, т.е. мы по сути передаем адрес на объект, что быстрее и менее затратно по памяти. Плюс ко всему мы работаем непосредственно с объектом, переданным по ссылке. Если же объект исключительно входной и не должен быть изменен, то следует добавить модификатор const:
Теперь, изменить объект object в функции не получится. Чтобы было возможно вызывать методы класса object они должны быть объявлены как const . Следует отметить, что есть понятие «ссылки на константу» а есть «константная ссылка». В данном случае мы имеем дело с первым понятием.
Теперь перейдем непосредственно к передаче объекта. Тут есть три варианта:
Просто передаем объект в функцию.
Тут несколько сложнее, т.к. мы создали указатель на объект. Указатель, по сути, адрес памяти. * перед ним является операцией разыменовывания, т.е. фактически передачей значения, как в первом случае.
Ситуация аналогична первому варианту. Теперь мы имеем ссылку на объект и передаем ее в функцию.
Передача объектов в функцию и возврат объектов
В качестве значения функция может возвращать объект. В этом случае может создаваться временный объект, а когда результат присваивается экземпляру класса может выполняться копирование, при этом вызывается конструктор копирования, а не обычный конструктор. Это важно учитывать, когда внутри класса используется динамическое выделение памяти. Если компилятор поддерживает оптимизацию вариантов RVO или NRVO , то при возврате объекта временный объект не создается и конструктор копирования не вызывается (см. разд. 13.6). Пример передачи объектов в функцию и возврат объектов приведен в листинге 13.22.
Листинг 13.22. Передача объектов в функцию и возврат объектов
Если при объявлении параметра дополнительно указать ключевое слово const , то внутри функции доступа к обычным методам объекта не будет. Например, создадим функцию func4() внутри которой вызовем метод dump() (см. листинг 13.22):
Попробуем вызвать функцию:
В результате получим следующую ошибку при компиляции:
Чтобы можно было вызвать метод dump() внутри функции func4() , следует его сделать константным:

Учебник C++ (Qt Creator и MinGW) в формате PDF
Помощь сайту
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов
ГЛАВА 14. ОБЪЕКТЫ И ФУНКЦИИ
Синтаксически объекты передаются в функции так же, как и простые переменные. Для этого объявляют параметр функции, который имеет тип класса. Затем используют объект этого класса в качестве аргумента при вызове функции.
Передача объекта в функцию по значению. По умолчанию происходит передача объектов в функцию по значению. При этом компилятор создаёт в функции копию переданного ей объекта, и функция работает с копией. Поэтому изменение копии объекта внутри функции не влияет на сам объект-оригинал.
// Пример.14.1. Передача объекта в функцию по значению.
using namespace std;
class Samp<
Samp(int n)
void set(int n)
int get()
// параметр – объект ob
ob.set(100); // изменяем копию объекта
Samp obj(10); // obj.x = 10
fun(obj); // передача ob по значению fun()
При вызове функции, в момент создания копии объекта, конструктор не вызывается, так как он используется для инициализации элементов объекта, а копия создаётся для уже существующего (а значит – проинициализированного) объекта.
При завершении работы функции созданная копия объекта удаляется и вызывается деструктор копии.
При передаче объекта в функцию по значению создаётся копия объекта. Конструктор копии не вызывается. Деструктор копии вызывается.
Передача объекта в функцию по указателю. При передаче объекта в функцию по указателю происходит передача в функцию адреса объекта. При этом функция может изменить значение элементов объекта, используемого в вызове. Функция fun() из примера 14.1 и её вызов будут иметь следующий вид:
p->set(p->get() + 50); // или просто p->set(60)
Samp ob(10); // создание объекта ob, x = 10
fun(&ob); // передача ob по указателю
Передача объекта в функции по ссылке. Ссылка является скрытым указателем и работает как другое имя объекта. При передаче объекта по ссылке изменения объекта внутри функции влияют на исходный объект и сохраняются при завершении работы функции.
Ссылка не является аналогом указателя, поэтому при передаче объекта по ссылке для доступа к его элементам используется операция точка (.), а не операция стрелка (->).
ref.set(ref.get() * ref.get()); // изменяем объект
// или так – ref.setx(100);
Samp ob(10); // создание объекта, ob.x = 10
fun(ob); // передача объекта ob по ссылке
Следует заметить, что передача оъекта по ссылке не всегда возможна.
// Пример 14.2. Определение класса для работы с рациональной дробью.
// Нахождение суммы двух рациональных дробей. Использование конструктора.
using namespace std;
class Frac<
Frac(int n, int m) // конструктор с параметром
double sumFrac(Frac s1, Frac s2)<
double z = (s1.geta()*s2.getb() + s1.getb()*s2.geta())/(s1.getb()*s2.getb());
cout<<«Vvedi chisl. i znam. for 1 fraction: «; cin>>x>>y;
Frac ob1(x, y); ob1.show();
cout<<«Vvedi chisl. i znam. for 2 fraction: «; cin>>x>>y;
Frac ob2(x, y); ob2.show();
double rez = sumFrac(ob1, ob2); cout<<«rez justify»> В общем случае только функции класса имеют доступ к закрытым членам этого класса. Однако в С++ существует возможность разрешить доступ к закрытым членам класса функциям, которые не являются членами класса. Для этого достаточно объявить эти функции дружественными по отношению к рассматриваемому классу. Для того чтобы объявить функцию дружественной некоторому классу, нужно в этот класс включить её прототип, перед которым поставить ключевое слово friend.
// Пример 14.3. Использование дружественной функции.
using namespace std;
class Samp<
Samp(int n, int m)
friend int fun(Samp ob); // друж. функция, параметр – объект
int fun(Samp ob)<
if(ob.x % ob.y == 0) return 1; else return 0; // прямой доступ к x и y
Samp ob(10, 5); // создание объекта ob1
if(fun(ob)) cout<<«ob.x kratno ob.y»<<endl;
else cout<<«ob.x no kratno ob.y»<<endl;
В данной программе дружественная функция fun() вызывается обычным образом. Так как дружественная функция не является членом того класса, для которого она дружественна, то её нельзя вызвать, используя имя объекта и операции точка (.) или стрелка (->).
Дружественная функция – это функция, определённая вне класса, но имеющая доступ ко всем членам класса.
Функция может быть дружественной более чем к одному классу.
// Пример 14.4. Функция fun() дружественна классу A и классу B.
using namespace std;
friend int fun(A o_a, B o_b); // дружественная функция
friend int fun(A o_a, B o_b);
int fun(A o_a, B o_b)
cout<<fun(ob_a, ob_b)<<endl; // 10
Следует обратить внимание на то, что в программе функция fun() определена только один раз, также используется опережающее объявление для класса B в связи с тем, что параметром функции fun() являетя объект класса B до определения класса.
Функция может быть членом одного класса и дружественной другому классу. Рассмотрим пример.
// Пример 14.5. Функция fun() член класса A и дружественна классу B.
using namespace std;
int fun(B o_b); // функция fun() – член класса A
friend int A::fun(B o_b); // функция fun() – друг класса B
A ob_a; B ob_b; // вызов функции fun() через
cout<<ob_a.fun(ob_b)<<endl; // операцию точка и объект класса A
Правила использования дружественных функций:
функция не является членом класса, но имеет доступ ко всем (в том числе и к закрытым) членам класса через объект, объявленный внутри функции или переданный ей в качестве аргумента;
функция вызывается как обычная функция;
прототип функции может быть объявлен как в открытой, так и в закрытой части класса, но она будет всё равно открытой;
функция может быть дружественной более чем к одному классу;
функция может быть членом одного класса и дружественной другому;
дружественной функции указатель this не передаётся.
// Пример 14.6. Нахождение суммы двух рациональных дробей.
// Использование конструктора, friend-функции.
using namespace std;
class Frac<
Frac()<>; // конструктор по умолчанию
Frac(int n, int m); // конструктор с параметром
void show(); // функция вывода
friend Frac sumFrac(Frac s1, Frac s2);
s3.a = (s1.a * s2.b + s1.b * s2.a);
cout<<«Vvedi chisl. i znam. for 1 fraction: «; cin>>x>>y;
Frac ob1(x, y); ob1.show();
cout<<«Vvedi chisl. i znam. for 2 fraction: «; cin>>x>>y;
Frac ob2(x, y); ob2.show();
Frac ob3 = sumFrac(ob1, ob2);
cout<<«sum justify»> system(«pause»);
Встраиваемые функции – члены класса
Язык программирования С++ позволяет задавать функции, которые не вызываются, а встраиваются в программу в месте её вызова. Использование таких функций не связано с механизмом их вызова и возврата из функции, следовательно, работают они гораздо быстрее обычных. Недостатком встраиваемых функций является то, что код программы возрастает. Из-за этого применение встраиваемых функций обычно ограничивается короткими функциями.
Любая функция может стать встраиваемой, включая функции-члены класса. Существует два способа создания встраиваемой функции-члена класса. Первый способ состоит в использовании спецификатора inline перед определением функции. Второй способ состоит в записи функции внутри определения класса, если функция достаточно короткая. Наиболее традиционным использованием встраиваемых функций, определяемых внутри класса, является определение конструктора и деструктора.
Как использовать объект класса в C++ в качестве параметра функции
Я не уверен, как иметь функцию, которая получает объект класса в качестве параметра. Любая помощь? Вот пример ниже.
В основном я просто запутался в том, как создать функцию, которая будет получать объект класса в качестве своих параметров, а затем использовать эти параметры внутри функции, например tempObject.variable .
Извините, если это немного сбивает с толку, я относительно новичок в C++.
@Adrian Пожалуйста, не придумывайте новые теги — их и так слишком много. — anon
5 ответы
class это ключевое слово, которое используется* только для введения определений классов. Когда вы объявляете новые экземпляры класса либо как локальные объекты, либо как параметры функции, вы используете только имя класса (которое должно быть в области видимости), а не ключевое слово. class себя.
Это определяет новый тип, называемый ANewType который является типом класса.
Затем вы можете использовать это в объявлениях функций:
Затем вы можете передавать объекты типа ANewType в функцию. Объект будет копироваться в параметр функции, поэтому, как и в базовых типах, любая попытка изменить параметр приведет к изменению только параметра в функции и не повлияет на объект, который был первоначально передан.
Если вы хотите изменить объект вне функции, как указано в комментариях в теле вашей функции, вам нужно будет взять объект по ссылке (или указателю). Например
Этот синтаксис означает, что любое использование object в теле функции относится к фактическому объекту, который был передан в функцию, а не к копии. Все модификации изменят этот объект и будут видны после завершения функции.
[* class ключевое слово также используется в определениях шаблонов, но это другая тема.]