Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТООП конспект весь.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
21.89 Mб
Скачать

Int main()

{

cout<<”Hello from C++!”<<endl;

return 0;

}

Заголовочные файлы Си доступны, но без .h и начинаются буквой с.

Все имена стандартной библиотеки С++ помещены в пространство имен с именем std.

Директива using делает напрямую без операции разрешения видимости видимыми все имена одного пространства имен в другом пространстве имен.

В примере делаются видимыми имена из std в глобальном безымянном пространстве.

Функция main должна располагаться в глобальном безымянном пространстве имен.

С++11 у функции main может быть 0,1 или 2 аргумента (3 не может быть).

cout - глобальная переменная, объект стандартного класса ostream.

extern ostream cout – стандартное устройство вывода

extern ostream cerr - стандартное устройство вывода ошибок

extern ostream clog - стандартное устройство вывода журналирования

extern istream cin – стандартный поток ввода

extern ostream cout – переопределена << для класса ostream (побитовый сдвиг влево), называется операцией помещения в поток.

char * выход в строку

Для другого выводится адрес (целое число, значение указателя).

(void*) char * - вывод адреса char

В классе ostream операция << (помещения в поток) переопределена для указателей на функции, получающие в качестве аргумента поток и возвращающие поток. Такая функция называется манипулятором потока.

endL – специальная функция манипулятор потока.

ostream (*) (ostream)

endL (что делает):

‘\n’

flush()

Общая структура программы на Java.

import java.lang.*;

public class Hello

{

public static void main (string[] args)

{

System.out.printLn(“Hello from Java”);

}

}

Директива import выполняет роль аналогичную using namespace в C++.

В Java не используется понятие пространство имен, а используется понятие пакет.

Пакет выполняет функции пространства имен, но имя пакета тесно связанно с файловой системой.

Откомпилированная программа должна сохраняться не в произвольном месте файловой системы, а в \java\Lang

Позволяет использовать несколько пакетов с одинаковыми именами.

В примере директива import делает напрямую видимыми все имена из пакета Java.Lang в глобальном безымянном пакете (благодаря *).

Если не использовать import писали бы Java.Lang.System

В Java внешние классы могут иметь модификатор видимости public, либо модификатор видимости на уровне своего пакета.

args – массив строк, содержащий аргументы командной строки

В Java всякий класс может иметь свой main.

out – статическое поле класса систем и объект стандартного класса PrintStream (стандартный вывод).

В PrintStream определен PrintLn.

В Java для любых типов и любых объектов разрешена операция конкатенации.

“a=”+1

Object

string to string

printf (“x=%d %f/n,10(1$),1.73(2$)”);

%2$f\t %1$%d\t - %1$%d\n -> 1.73 10 -10

Java SDK (oracle.com/java)

  1. javac Hello.java

Hello.class

  1. java Hello интерпретатор виртуальной машины java

Имя исходника java должно совпадать с именем public класса.

classLoader – загружает файлы.

Общая структура программы на C#

using System;

public class Hello

{

public static void Main() //string[] args | args.length

{

console.WriteLine(“Hello from C#!”);

}

}

using system – конструкция, как в С++, которая делает видимым напрямую все имена из пространства имен system в безымянном пространстве имен.

Текст программы можно разместить в любом файле.

имя.cs

a.cs

Main можно задать без аргументов, либо с одним аргументом.

public – класс доступен вне сборки (в других сборках).

.Net Framework SDK -> csc.exe a.cs

a.exe -> .Net

Перегрузка операций в С++ (значков операций).

operator overloading

Ограничения на перегрузку операций:

  1. нельзя перегружать операции:

. операция доступа к полю класса или вызова метода класса

.* операция доступа к полю класса или вызова метода класса через указатель на метод класса

?: оператор условия

:: разрешение области видимости

sizeof

typeid определение типа объекта на этапе выполнения программы

dynamic_cast<>, static_cast<>, veinterpret_cast<>, const_cast<> операции привидения типа

throw выбрасывает (генерирует) исключения.

Остальные можно перегружать.

  1. нельзя придумать новый значок операции

  2. нельзя переопределять операции для встроенных типов (можно только для своих классов).

  3. нельзя изменять приоритет, ассоциативность и арность операций.

  4. перегруженные операции не могут получить значение аргументов по умолчанию.

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

= () [] -> можно перегружать только методом класса.

Некоторые виды операций можно переопределять только с помощью внешние функции.

Все перегруженные операции, кроме присваивания наследуют.

Перегрузки операции сложения (пример).

operator+

нужно определить для класса внешнюю функцию, либо метод с именем operator+

class A

{

int a;

public:

/*explicit*/ A(int x=0) : a(x) {}

int getA() {return a;}

void setA (int x) {a=x;}

??? & A operator+ (A a2)

{

return A(a+a2.a);

//(this->a+a2.a)

}

};

A a1, a2;

  1. a1.operator+(a2) -> & a1 this

  2. operator+(a1,a2)

Конструктор класса А может использоваться для преобразования целочисленной величины int в объект класса.

a1+1 -> a1.operator+(1) (разрешено, (1) – временный объект)

void f (A a);

f(10); // A tmp (10);

если перед конструктором написать explicit, то а1+1 – нельзя выполнить.

Если operator+ получает ссылку на а, то значит, будет передаваться адрес, новый временный объект создаваться не будет, поэтому не будет преобразования целого объекта.

Для того, чтобы выражение а1+1 работало всегда (даже когда не разрешено преобразование целого в объект А) нужно перегрузить операцию сложения – в описании класса добавить еще одну версию оператора +

A operator+ (int a2)

{

return A (this->a+a2);

}

a1.operator+ (1) <- a1+1

1.operator+ (a1) <- 1+a1

Выражение (1+а1) может быть использовано в программе, если существует внешняя функция с именем operator+ и двумя аргументами: первый типа int, второй – объект класса А.

Мы должны для класса определить внешнюю функцию с именем operator+

operator+ (int, a1).

A operator+ (int a2)

{

return A (this -> a + a2);

friend ostream & operator << (ostream & o, A & a);

};

A operator+ (int x, A & a1)

{

return A (x+a1.a);

}

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

Переопределить операции помещения в поток.

class A

{

int a;

public:

A(int x=0) : a(x) {}

int getA() {return a;}

void setA (int x) {a=x;}

/*cout – объект чужого, но стандартного класса в С++ iostream*/

/*Операция помещения в поток (<<(и операцию извлечения из потока >>)) можно переопределить для своего класса только с помощью внешней функции, а не метода*/

ostream & operator << (ostream & o, A & obj)

return o <<obj.getA(); // <-a int

}

operator ++ () -> ++x префиксная

operator ++ (int) -> x++ постфиксная

Синтаксическая разница должна быть такая.

Операция вызова метода класса через указатель на метод класса.

.*

-> * операция вызова чего-то там. Ее можно перегрузить.

void f();

void (* pf) ();

pf=&f; // pf=f;

pf();

Метод имеет тип как и внешняя функция, но привязан к классу.

class A

{

public:

int a;

int getA() {return a;}

void setA (int x) {a=x;}

int getAZ() {return a*a;}

};