Объекты-результаты функций

Объекты как аргументы.

Предположим мы имеем некоторый класс, который содержит в себе два объекта, величины, которых нам необходимо сложить. Для этого мы используем некоторую функцию, в качестве аргументов которой, мы передаём объекты. Синтаксис передачи объектов в функцию такой же, как и для переменных стандартных типов; на месте аргумента указывается имя объекта. Но обязательно, нужно учесть, является ли эта функция методом класса, ведь от этого зависит доступ к защищенным полям объектов.

Так же необходимо упомянуть ещё несколько важных деталей, касающихся методов класса. Методу класса всегда предоставлен доступ к полям объекта, для которого он вызван: объект связан с методом операцией точки. Однако па самом деле методу класса доступны и другие объекты.

Таким образом, подводя итог вышесказанному, мы можем утверждать, что каждый вызов метода класса обязательно связан с конкретным объектом этого класса (исключением является вызов статической функции). Метод может прямо обращатьсяпо к любым, открытым и закрытым, членам этого объекта. Кроме того, метод имеет непрямой доступ к членам других объектов своего класса; последние выступают в качестве аргументов метода.

Рассмотрим пример в котором объекты будут использоваться в качестве аргументов:

Пример 12:

#include <iostream>

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <conio.h>

using namespace std;

class A

{public:

int i;

void vvod()

{ cout<<"vvedite chislo\n";

cin>>i;

}

};

int sum(A a,A b)

{ int n;

n=a.i+b.i;

return n;

}

int main()

{ int i;

A obj1;

A obj2;

obj1.vvod();

obj2.vvod();

i=sum(obj1,obj2);

cout<<i;

return 0;

}


В рассмотренном выше примере мы убедились в том, что объекты могут быть использованны в качестве аргументов функции. Однако на этом возможности С++ не ограничеваются. Здесь объекты так же могут быть редставленны как результаты различных функций. Синтексис остаётся прежний, как и с простыми переменными. Для более подробного знакомства с подобными случаями, рассмотрим пример с использованием функций в качестве результатов которых будут объекты.
Пример 13:

#include <iostream>

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <conio.h>

using namespace std;

class A

{public:

int i;

void vvod()

{

cout<<"vvedite chislo\n";

cin>>i;

}

void vuvod()

{

cout<<i;

}

};

void sum(A a,A b)

{

A c;

c.i=a.i+b.i;

c.vuvod();

}

int main()

{

int i;

A obj1;

A obj2;

obj1.vvod();

obj2.vvod();

sum(obj1,obj2);

return 0;

}

6.7 Массивы объектов класса.

Мы уже знаем, что объекты могут содержать массивы. Но верно и обратное: мы можем создать массив объектов.

Границы массива.

Что случится, если пользователь введет более n (n-размер массива) интервалов? Что-то непредвиденное, но почти определенно плохое. В С++ нет проверки границ массива. Если программа поместит что-то за пределами массива» то компилятор и исполняемая программа протестовать не будут. Однако эти данные могут быть записаны поверх других данных или поверх самой программы. Это может послужить причиной странных эффектов или даже полного краха системы.

Мораль всего этого такова, что программисту следует применять проверку границ массива. Если возникает возможность переполнения массива данными, то он должен иметь большие размеры или у него должна быть возможность предупредить пользователя овозможном переполнении.

Доступ к объектам в массиве.

Допустим мы имеем класс и мы хотим создать массив, состоящий из объектов этого класса. Таким образом, типом данных создаваемого массива является класс. Доступ к методам объектов элементов массива похож на доступ к членам структуры, являющейся элементом массива.

Доступ к методу объекта, являющегося элементом массива, осуществляется с помощью операции точки. За именем массива следует доступ к полям объекта, для которого он вызван: объект связан с методом операцией точки. За именем массива следуют квадратные скобки, в которые заключен индекс элемента, затем операция точки и имя метода, за ними следуют скобки. Это похоже на доступ к полю структуры (или класса), за исключением того, что вместо имени переменной используется имя метода со скобками.

Таким образом, можно подвести итоги о массивах объектов и просто о массивах вообще. Итак, массивы содержат набор данных одинакового типа. Этот тип может быть простым типом, структурой или классом. Члены массива называются элементами. К элементам можно получить доступ, используя число, которое называется индексом. Элементы могут быть инициализированы определенным значением при определении массива. Массив может иметь несколько размерностей. Двумерный массив это массив массивов. Адрес массива может быть использован как аргу­мент функции; сам массив при этом не копируется. Массив может быть использован как переменная класса. Необходимо позаботиться о том, чтобы данные не были помещены за пределы массива.

А теперь рассмотрим пример с использованием массива объектов.

Пример 14:

#include <iostream>

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <conio.h>

using namespace std;

class MArray

{

protected:

int size;

int A[50];

public:

MArray(){size=0;};

MArray(int Size)

{

int i;

size=Size;

for(i=0;i<size;i++)

{

A[i]=i;

//C[i]=i;

}

};

~MArray(){};

};

class nasl:public MArray

{

public:

void Keyboard()

{ int i;

for(i=0;i<size;i++)

{

cin>>A[i];

}

};

void DisplayA()// функция вывода массива на экран

{

int i;

for(i=0;i<size;i++)

{

cout<<" "<<A[i];

}

};

nasl(int n):MArray(n){};

nasl(){};

~nasl(){};

};

int main()

{

int i,din;

cout<<"Vvedite din\n";

cin>>din;

nasl ** matrix;

matrix = new nasl *[din];

for (i=0;i<din;i++)

{

matrix[i]=new nasl(din);

matrix[i]->Keyboard();

}

for (i=0;i<din;i++)

{

matrix[i]->DisplayA();

}

return 0;

}

6.8 Абстрактный класс.

Базовый класс, объекты которого никогда не будут реализованы, называется абстрактным классом. Такой класс может существовать с единственной целью — быть родительским по отношению к производным классам, объекты которых будут реализованы. Ещё он может служить звеном для создания иерархической структуры классов.

Возникает проблема: объекты родительского класса не предназначены для реализации, поэтому необходимо предусмотреть защиту нашого базового класса от использования не по назначению. Правильней всего это сделать программно. Для этого достаточно ввести в класс хотя бы одну чистую виртуальную функцию (см. п. 5.6). Раньше мы рассмотрели просто виртуальные функции. В таком случае, возникает вопрос, а что же такое чистая виртуальная функция. А это ни что другое, как функция, после объявления, которой добавлено выражение «0». То есть:

virtual void funkciya()=0

Знак равенства не имеет ничего общего с операцией присваивания. Нулевое значение ничему не присваивается. Конструкция =0 — это просто способ сообщить компилятору, что функция будет чистой виртуальной. Если теперь в main() попытаться создать объект абстрактного класса, то компилятор будет недоволен тем, что объект абстрактного класса пытаются реализовать. Он выдаст даже имя чистой виртуальной функции, которая делает класс абстрактным.

Таким образом, как только в базовом классе окажется чистая виртуальная функция, необходимо будет позаботиться о том, чтобы избежать ее употребления во всех производных классах, которые вы собираетесь реализовать. Если класс использует чистую виртуальную функцию, он сам становится абстрактным, никакие объекты из него реализовать не удастся. Рассмотрим подобную конструкцию в следующем примере:

Пример 15:

#include <iostream>

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <conio.h>

using namespace std;

class MArray

{protected:

int size;

int A[50];

public:

MArray(){size=0;};

MArray(int Size)

{ int i;

size=Size;

for(i=0;i<size;i++)

{

A[i]=i;

//C[i]=i;

}

};

~MArray(){};

};

class nasl:public MArray

{

public:

void Keyboard()

{

int i;

for(i=0;i<size;i++)

{

cin>>A[i];

}

};

void DisplayA()// функция вывода массива на экран

{

int i;

for(i=0;i<size;i++)

{

cout<<" "<<A[i];

}

};

nasl(int n):MArray(n){};

nasl(){};

~nasl(){};

};

class A:public MArray

{

virtual void funkciya()=0;

};

int main()

{ int i,din;

cout<<"Vvedite din\n";

cin>>din;

nasl ** matrix;

matrix = new nasl *[din];

for (i=0;i<din;i++)

{ matrix[i]=new nasl(din);

matrix[i]->Keyboard();

}

for (i=0;i<din;i++)

{

matrix[i]->DisplayA();

}

return 0;

}



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: