Выбери формат для чтения
Загружаем конспект в формате pdf
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Свойства объектов в языках С++, Java
1) Вызов метода внутри класса
Метод может вызвать другой метод класса, при этом методу передаются значения полей
С++
Класс треугольник, метод вычисления площади по 3 сторонам.
S p( p a )( p b)( p c)
p=(a+b+c)/2 - полупериметр
Пусть периметр - вспомогательный метод, нужен только для вычисления площади, тогда
метод P() – private
#include
#include
class treug
{
public:
float S(); // вычисление площади
void Read();
private:
float P(); // вычисление периметра, метод нужен только для вычисления S
float a,b,c;
};
void treug::Read()
{
scanf("%f %f %f",&a,&b,&c);
}
float treug::P()
{
return a+b+c;
}
float treug::S()
{
float p;
p=P()/2; // вызов P() - без использования объекта типа trug x; p=x.P()/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
int _tmain(int argc, _TCHAR* argv[])
{
1
treug D;
float x;
D.Read();
x=D.S();
printf("%f \n",x);
x=D.P();
// ошибка, P() - private
x=S();
// ошибка функция S() отсутствует
return 0;
}
На Java аналогично.
2) Константы в C++, Java
Константа на Си:
#define N 10
..........
int mas[N],mas1[N];
Константа на С++:
const int N=10;
..................
int mas[N],mas1[N];
Константа на Java:
final static int N=10;
...................
int mas[] = new int[N];
3) Пакеты на Java
Пакет позволяет разнести классы по отдельным файлам и обеспечить связь между полями и
методами различных классов. Пакет – отдельный каталог, в котором размещается
несколько файлов – public классов.
Пример создания пакета
Создание проекта: file – new – java project (lab4)
2
Создание пакета: file – new – Package (sports)
Создание отдельных 3 файлов-public классов
file - new – class
package sports;
public class Record
{
protected int min,sec;
public void Init(int m,int s)
{
min=m;
sec=s;
}
public int Numbersec()
{
return min*60+sec;
}
}
package sports;
public class Sportsman
{
private int Straf; // дополнительное поле
private Record r1 = new Record(); // поле типа Record
private Record r2 = new Record(); // поле типа Record
public void Init(int v,int m1,int s1,int m2,int s2)
{
Straf=v;
r1.Init(m1, s1); // инициализация первого результата
r2.Init(m2, s2); // инициализация второго результата
}
public int Sum() // общее число секунд
{
int k;
k=r1.Numbersec(); // секунды первого
k=k+r2.Numbersec(); // плюс секунды второго
k=k+Straf*60;
// штраф
return k;
}
package sports;
public class worksport
{
public static void main (String args[] )
{
Sportsman a=new Sportsman();
int k,m;
a.Init(1,2,6,1,55);
3
k=a.r1.Numbersec();
m=a.Sum();
System.out.printf("ответ %d %d",k,m);
}
}
Размещение:
lab4\\src\\sports\\
record.java Sportsman.java worksport.java
4)Массивы вспомогательных объектов на C++ и Java
Замена полей объектов вспомогательных классов массивом объектов вспомогательных
классов
C++ динамический массив
#include "stdafx.h"
#include
#include
#include
const int N=10; // максимальное число результатов
class Record
{
private:
int min,sec;
public:
void Init(int m,int s);
void Display();
};
void Record::Init(int m,int s)
{
min=m;
sec=s;
}
void Record::Display()
{
printf("%d %d\n",min,sec);
}
class Sportsman
{
private:
Record *records; // динамический массив
int n;
// текущее количество
char fam[30];
4
public:
void Init(char *f);
void AddResult(int m, int s) ; // добавление в конец массива
void Display();
void Insert(int k,int m,int s) ;
};
void Sportsman::Init(char*f)
{
strcpy(fam,f);
records=new Record[N]; // N - максимальное число результатов
n=0;
// у нового спорсмена нет результатов
}
void Sportsman::Display()
{
int i;
printf("%s\n",fam);
for(i=0;iInit(m,s);
records[n]=*c;
n++;
}
void Sportsman::Insert(int k,int m,int s) // вставка результата на место k
{
int i;
for(i=n;i>k;i--)
{
records[i] = records[i - 1];
}
Record *c;
c=new Record;
c->Init(m, s);
records[k] = *c;
n++;
}
int _tmain(int argc, _TCHAR* argv[])
{
Sportsman a;
a.Init("Иванов");
5
a.AddResult(3, 5);
a.AddResult(3, 6);
a.AddResult(3, 7);
a.AddResult(3, 8);
a.AddResult(3, 9);
a.Insert(2, 4, 1);
a.Display();
return 0;
}
Java
package javaapplication4;
class Record
{
private int min,sec;
public void Init(int m,int s)
{
min=m;
sec=s;
}
public void Display()
{
System.out.printf("%d %d\n", min,sec);
}
}
public class Sportsman
{
final static int N=10; // константа на java
private String fam;
private Record [] records =new Record[N];
int n;
6
public void Init(String f)
{
fam=f;
n=0;
}
public void Display()
{
int i;
System.out.printf("%s\n",fam);
for (i = 0; i < n; i++)
// вывод всех результатов
{
records[i].Display();
}
}
public void AddResult(int m, int s) // добавка результата в конец массива
{
Record c=new Record();
c.Init(m, s);
records[n] = c;
n++;
}
public void Insert(int k,int m,int s) // вставка результата на место k
{
int i;
for(i=n;i>k;i--)
{
records[i] = records[i - 1];
}
Record c=new Record();
c.Init(m, s);
records[k] = c;
n++;
}
public static void main(String[] args)
{
Sportsman a=new Sportsman();
a.Init("Иванов");
a.AddResult(3, 5);
a.AddResult(3, 6);
a.AddResult(3, 7);
a.AddResult(3, 8);
a.AddResult(3, 9);
a.Insert(2, 4, 1);
a.Display();
}
}
7
5) Передача аргументов методов на C++ и Java. Перегрузка функций
В языках программирования в одном модуле можно определить несколько функций с
одинаковыми именами (перегружать функции). Необходимо, чтобы у них было различное
число аргументов и/или различный тип аргументов. Различие в возвращаемом типе
недостаточно.
На языке Си для вычисления абсолютной величины числа необходимо задать 2 функции:
int abs(int x)
{
if(x>=0)
return x;
else
return -x;
}
float fabs(double x)
{
if(x>=0)
return x;
else
return -x;
}
main:
double y,z;
int a,b;
.......
z=fabs(y);
......
b=abs(a);
8
На C++, Java возможны функции с одинаковыми именами в одном модуле, перегрузка
функций.
Пример С++
int abs(int x) // 1 функция
{
if(x>=0)
return x;
else
return -x;
}
float abs(double x) // 2 функция, обе функции названы одинаково!
{
if(x>=0)
return x;
else
return -x;
}
main:
double y,z;
int a,b;
.......
z=abs(y); // какая функция вызвана, определяется типом фактического параметра 2
функция
......
b=abs(a); // вызывается 1 функция
// float abs(int x) // ошибка, с такими аргументами функция есть, различие типов
// недостаточно
Функция ввода:
int scanf("%d",&x);
В x находится значение, введенное с консоли, а функция вернет 1( одно, число введено).
Возможен также случай, когда необходимо тоже вернуть результат не через функцию, а через
один из аргументов (например, в случае получения нескольких результатов).
9
Си:
Обычные аргументы не возвращают значений - передача параметра по значению.
Неверное решение.
class Record
{
private:
int min,sec;
public:
void Init(int m,int s);
int Numbersec(); // результат- через функцию
void Numbersec(int x); // через аргумент, обе функции в одном классе, перегрузка
};
void Record::Init(int m,int s)
{
min=m;
sec=s;
}
int Record::Numbersec()
{
return min*60+sec;
}
void Record::Numbersec(int x)
{
x=min*60+sec;
return;
}
main()
{
...
Record a;
int k,m;
a.Init(2,10);
k=1;
m=a.Numbersec(); // m=130, правильно
a.Numbersec(k); // вызов второго метода k=1, значение прежнее !
}
Для получения значения через аргумент в Си используются указатели.
class Record
10
{
private:
int min,sec;
public:
void Init(int m,int s);
int Numbersec(); // результат через функцию
void Numbersec(int *x); // параметр указатель
};
......
void Record::Numbersec(int *x)
{
*x=min*60+sec; // присваивание через указатель
return;
}
main()
{
...
Record a;
int k,m;
a.Init(2,10);
k=1;
m=a.Numbersec(); // m=130, правильно
a.Numbersec(&k); // передача адреса k=130
}
C++
На C++ возможно получение значения через параметр ссылку.
class Record
{
private:
int min,sec;
public:
void Init(int m,int s);
int Numbersec(); // результат через функцию
void Numbersec(int *x); // через параметр указатель
void Numbersec(int &x); // через параметр ссылку
};
void Record::Init(int m,int s)
{
min=m;
sec=s;
}
int Record::Numbersec()
{
11
return min*60+sec;
}
void Record::Numbersec(int *x)
{
*x=min*60+sec;
return;
}
void Record::Numbersec(int &x)
{
x=min*60+sec;
return;
}
main()
{
...
Record a;
int k,m,n;
a.Init(2,10);
k=1;
m=1;
n=1;
m=a.Numbersec(); // вызов первого методаm=130, правильно
a.Numbersec(&k); // вызов второго метода k=130
a.Numbersec(n); // вызов третьего метода n=130
}
Java
На Java переменные передаются по значению (не возвращаемый параметр), а объекты по
ссылке (возвращаются измененные поля объекта).
Пример возвращения целого числа через вспомогательный класс из одного поля.
class Rezult // вспомогательный класс для получения результата Numbersec
{
public int param; // единственное поле
}
class Record
{
private int min,sec;
public void Init(int m,int s)
{
min=m;
sec=s;
}
public void Display()
{
12
System.out.printf("%d %d \n",min,sec);
}
public int Numbersec() // значение через функцию
{
return min*60+sec;
}
public void Numbersec(Rezult k) // значение через аргумент - класс
{
k.param=min*60+sec; // param – public – есть доступ из др. класса
}
}
public class lab4
{
public static void main(String[] args)
{
Record c=new Record();
int m,k;
Rezult z=new Rezult(); // объект класса для получения результата
c.Init(2, 10);
m=c.Numbersec(); // первый метод
c.Numbersec(z); // второй метод
k=z.param;
// k - результат, param - public
System.out.printf("%d %d\n",m, k);
}
}
130 130
6) Указатель (ссылка) на объект, вызывающий метод - this
C++
В классе Record к методу Srednee с двумя аргументами добавим метод Srednee с одним
(вторым) аргументом (Перегрузка). Первым аргументом будет вызывающий объект
class Record
{
public:
void Init(int m,int s);
Record Srednee(Record a,Record b);
Record Srednee(Record b);
private:
int min;
int sec;
};
void Record::Init(int m,int s)
{
13
min=m;
sec=s;
}
Record Record::Srednee(Record a,Record b)
{
Record c;
int k;
c.min=a.min+b.min;
k=a.sec+b.sec;
if(k>=60)
{
c.min++;
k=k-60;
}
c.min=c.min/2;
c.sec=k/2;
return c;
}
Record Record::Srednee(Record b)
{
Record c;
int k;
c.min=this -> min+b.min; // this -> - указатель на объект, который вызовет метод
k=this -> sec+b.sec;
if(k>=60)
{
c.min++;
k=k-60;
}
c.min=c.min/2;
c.sec=k/2;
return c;
}
int main(int argc, char* argv[])
{
int m,s,k;
Record x,y,z;
x.Init(4,36); // min=4 sec=36
y.Init(2,4); // min=2 sec=4
z=z.Srednee(x,y); // вызов 1 функции z.min=3 z.sec=20 (x+y) /2
z=x.Srednee(x,y); // вызов 1 функции z.min=3 z.sec=20
z=x.Srednee(y); // вызов 2 функции z.min=3 z.sec=20 (x+y) /2
z=z.Srednee(y); // вызов 2 функции z.min=2 z.sec=12 (z+y) /2
}
14
Указатель this-> можно не использовать (this->min заменить на min). Поле без объекта
методе означает поле вызывающего объекта.
c.min=min+b.min;
Java
public class Record
{
private int min;
private int sec;
public int Numbersec()
{
return min*60+sec;
}
public void Init(int m,int s)
{
min=m;
sec=s;
}
public Record Better(Record a,Record b) // с двумя аргументами лучшее время из двух
{
int s1,s2;
s1=a.Numbersec();
s2=b.Numbersec();
if(s1=30
вернуть количество минут+1.
#include "stdafx.h"
class Record
{
private:
int min,sec;
public:
void Init(int m,int s);
friend int Roundmin(Record x); // дружественная функция свободная, вне класса
};
void Record::Init(int m,int s)
{
min=m;
sec=s;
}
int Roundmin(Record x) // нет Record::
{
if(x.sec>=30)
16
return x.min+1;
else
return x.min;
}
int _tmain(int argc, _TCHAR* argv[])
{
int k;
Record a,b,c,d;
a.Init(2,35);
k=Roundmin(a); // k=3
return 0;
}
Если убрать строку :
friend int Roundmin(Record x);
ошибка:
int Roundmin(Record x)
{
if(x.sec>=30)
// доступ к private полю sec вне класса
return x.min+1; // min - private !
else
return x.min;
}
Если min, sec сделать public, Roundmin работает без указания friend.
Можно сделать класс A полностью дружественным B.
8) Перегрузка операторов на C++
Примеры перегрузки операторов на C++
char a,b;
b=12;
// в двоичной системе 00001100
a= b << 2; // логический сдвиг a: 00110000
Если слева от оператора << объект cout, выполняется вывод значения величины справа от <<
cout << a;
Аналогично можно выполнить перегрузку операторов ++, +, * и т.д. для произвольных
объектов.
C++
Пример перегрузки оператора + для класса Record. При сложении двух объектов Record
складываются значения полей, при добавлении к объекту числа, оно добавляется к sec.
17
class Record
{
private:
int min,sec;
public:
void Init(int m,int s);
Record operator + (Record b); // сложение двух объектов operator +
};
void Record::Init(int m,int s)
{
min=m;
sec=s;
}
Record Record::operator+(Record b)
{
Record c;
c.min=this->min+b.min;
c.sec=this->sec+b.sec;
if(c.sec>=60)
{
c.min++;
c.sec -= 60;
}
return c;
}
int _tmain(int argc, _TCHAR* argv[])
{
Record a,b,c,d;
a.Init(2,25);
b.Init(2,45);
c.Init(3,5);
d=a+b+c; // d: min = 8 sec = 15
return 0;
}
Перегрузка '+' , когда справа от '+' - число.
#include "stdafx.h"
class Record
{
private:
int min,sec;
18
public:
void Init(int m,int s);
Record operator + (Record b);
Record operator + (int b);
// сложение с числом справа
};
void Record::Init(int m,int s)
{
min=m;
sec=s;
}
.........
Record Record::operator+(int b) // сложение с числом справа
{
Record c;
c.min=this->min;
c.sec=this->sec+b; // добавка к секундам
if(c.sec>=60)
{
c.min++;
c.sec -= 60;
}
return c;
}
int _tmain(int argc, _TCHAR* argv[])
{
int k;
Record a,b,c,d;
a.Init(2,35);
a=a+45; // a: min=3 sec=20
return 0;
}
#include "stdafx.h"
class Record
{
private:
int min,sec;
public:
void Init(int m,int s);
Record operator + (Record b);
Record operator + (int b);
friend Record operator +(int b,Record x); // дружественный оператор
};
19
void Record::Init(int m,int s)
{
min=m;
sec=s;
}
.....
Record operator +(int b,Record x) // отсутствуют Record::
{
Record c;
int k;
c.min=x.min;
c.sec=b+x.sec;
if(c.sec>=60)
{
c.min++;
c.sec=c.sec-60;
}
return c;
}
int _tmain(int argc, _TCHAR* argv[])
{
int k;
Record a,b,c,d;
a.Init(2,35);
b=15+a; // b: min =2 sec =50
return 0;
}
Аналогично можно перегрузить *, / и т.д. , определив операции над объектами Record, но
приоритет операций сохраняется.
z=x+a*v; - сначала умножение, потом сложение.
Пример перегрузки префиксного и постфиксного оператора ++
Операторы увеличивают значение min на 1.
Различие между операторами:
int n,m;
n=1;
m=2;
n=++m; // m=3 n=3 сначала увеличить, потом присвоить
n=1;
20
m=2;
n=m++; // n=2, m=3 сначала присвоить, потом увеличить
class Record
{
private:
int min,sec;
public:
void Init(int m,int s);
Record & operator ++();
Record operator ++(int unused);
};
void Record::Init(int m,int s)
{
min=m;
sec=s;
}
Record & Record::operator ++() // prefix
{
this->min++;
return *this;
}
Record Record::operator++(int unused) // postfix
{
Record c = *this;
++*this;
return c;
}
int _tmain(int argc, _TCHAR* argv[])
{
Record a,b;
a.Init(2,35);
b=++a;
//a: min=3 sec=35 b: min=3 sec=35
a.Init(2,35);
b=a++;
//a: min=3 sec=35 b: min=2 sec=35
return 0;
}
9)Работа со строками на C++, Java
строка на Си – массив char или указатель:
#include
#include // строки на Си
#include
21
Строки на Си – массив символов
int main(int argc, char* argv[])
{
int k;
char a[30]; // массив char – 1 вариант строки, длина не более 29 символов, в конце 0
char *b;
// указатель, необходимо выделить память
b=(char *)calloc(30,1); // 2 вариант строки после выделения памяти
strcpy(b,”1234”); // копирование строки b[0]=’1’ b[1]=’2’ b[2]=’3’ b[3]=’4’ b[4]=’\0’
// строка оканчивается нулевым кодом
// b=”1234”; // присваивается указатель константы, источник многих ошибок
// strcat(b,"567"); // для b теперь только 5 байт
printf("%s\n ",b); // вывод строки на консоли: 1234 и перевод строки
strcpy(a,b);
// a: 1234 в конце нуль - вместо присваивания a=b
strcat(a,”56”); // сцепление строк a: 123456 в конце нуль
puts(a);
// вывод строки на консоли: 123456 без перевода строки
if(strcmp(a,b) ==1) // значения strcmp(a,b) -1:ab
k=strlen(a); // если условие выполнено k=6 - длина строки
free(b); // не забыть освободить память
}
На C++, Java строки представляют отдельные классы
С++
#include
using namespace std;
int main(int argc, char* argv[])
{
string c; // объект с класса string
}
using namespace std; - пространство имен указывается для заголовочных файлов C++ <...> без
.h (#include - библиотека Си)
Некоторые варианты задания строк C++
string a;
string b(“12345”);
string c[10];
// массив строк от c[0] до c[9]
string d[3]={“11”,”222”,”3333”}; // 1 параметр и инициализацией массива
на C++ присваивание перегружено для строк:
string a(“”);
// пустая строка
string b("12345");
a=b;
// a=”12345”
22
на C++ операторы < <= == > >= != перегружены - сравнение:
string a("12345");
string b("1245");
if(a, == - для строк не определены.
24
Для сравнения используется метод CompareTo:
s1="1234567";
s2="123868";
k=s1.compareTo(s2); // k=-4 разность первых несовпадающих кодов (4-8)
k<0 первая строка меньше второй, k=0 строки равны, k>0 первая строка больше второй
К символам строки нельзя обращаться как к элементам массива.
Выбор отдельного символа строки метод charAt:
char c;
s1="1234567";
c=s1.charAt(3); // c=’4’
Перевод строки в массив байт getBytes():
byte bt[]=new byte[20];
s1=”1234567”;
bt=s1.getBytes(); // bt[0]=’1’ bt[1]=’2’ ...
Выделение подстроки:
s1="1234567";
s2=s1.substring(3, 5); // s2==”45” (с третьего по пятый-1)!! с нуля
Поиск подстроки:
int k;
s1="1234567";
k=s1.indexOf("56"); // k=4 (k=0 с начала строки k=-1 не найдено)
Длина строки:
int k;
s1="1234567";
k=s1.length(); // k=7
25