Как передать объект класса в функцию c
Перейти к содержимому

Как передать объект класса в функцию c

  • автор:

Как передать объект класса по ссылке?

Весь вопрос в шапке, но продублирую: Как передать объект класса по ссылке?

Denis SafonoV's user avatar

Передача объекта по ссылке используется достаточно часто и описана во многих книгах по С++, однако не всем получается быстро понять данный механизм.

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

К типу передаваемого объекта добавляется символ & , причем его можно размещать как вплотную к типу, так и к имени объекта. Это зависит от стиля программирования.

При передачи объекта по ссылке не происходит копирования, т.е. мы по сути передаем адрес на объект, что быстрее и менее затратно по памяти. Плюс ко всему мы работаем непосредственно с объектом, переданным по ссылке. Если же объект исключительно входной и не должен быть изменен, то следует добавить модификатор const:

Теперь, изменить объект object в функции не получится. Чтобы было возможно вызывать методы класса object они должны быть объявлены как const . Следует отметить, что есть понятие «ссылки на константу» а есть «константная ссылка». В данном случае мы имеем дело с первым понятием.

Теперь перейдем непосредственно к передаче объекта. Тут есть три варианта:

Просто передаем объект в функцию.

Тут несколько сложнее, т.к. мы создали указатель на объект. Указатель, по сути, адрес памяти. * перед ним является операцией разыменовывания, т.е. фактически передачей значения, как в первом случае.

Ситуация аналогична первому варианту. Теперь мы имеем ссылку на объект и передаем ее в функцию.

Передача объектов в функцию и возврат объектов

В качестве значения функция может возвращать объект. В этом случае может создаваться временный объект, а когда результат присваивается экземпляру класса может выполняться копирование, при этом вызывается конструктор копирования, а не обычный конструктор. Это важно учитывать, когда внутри класса используется динамическое выделение памяти. Если компилятор поддерживает оптимизацию вариантов RVO или NRVO , то при возврате объекта временный объект не создается и конструктор копирования не вызывается (см. разд. 13.6). Пример передачи объектов в функцию и возврат объектов приведен в листинге 13.22.

Листинг 13.22. Передача объектов в функцию и возврат объектов

Если при объявлении параметра дополнительно указать ключевое слово const , то внутри функции доступа к обычным методам объекта не будет. Например, создадим функцию func4() внутри которой вызовем метод dump() (см. листинг 13.22):

Попробуем вызвать функцию:

В результате получим следующую ошибку при компиляции:

Чтобы можно было вызвать метод dump() внутри функции func4() , следует его сделать константным:

Учебник C++ (Qt Creator и MinGW)
Учебник 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) // функция установки x

int get() // функция чтения x

// параметр – объект 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) // функция fun()

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 ключевое слово также используется в определениях шаблонов, но это другая тема.]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *