- В методе объектно-ориентированного проектирования система рассматривается как набор объектов (т. е. сущностей). Состояние распределяется между объектами, и каждый объект обрабатывает данные о своем состоянии…….(Посетите, чтобы узнать больше)
- c++ — это простой, статический, скомпилированный, универсальный, высокоуровневый, объектно-ориентированный язык программирования.
Абстракция VS Инкапсуляция
Конструктор С++
- Конструктор — это специальный тип функции-члена, который вызывается автоматически при создании объекта.
- В C++ конструктор имеет то же имя, что и класс, и не имеет возвращаемого типа.
#include<iostream> using namespace std; class Base{ public: // create constructor Base(){ cout<<"This is Constructor function."<<endl; } }; int main(){ Base B; return 0; }
Тип конструктора
- Конструктор по умолчанию
- Параметризованный конструктор
- Копировать конструктор
Параметрический конструктор
- В C++ конструктор с параметрами называется параметризованным конструктором. Это предпочтительный метод для инициализации данных членов.
// parameterized constructor #include using namespace std; class Base{ private: int length; public: // constructor Base(int len){ length = len; } int getdata(){ return length * 2; } }; int main(){ Base B(10); cout<<B.getdata()<<endl; return 0; }
Конструктор копирования
- Конструктор копирования в C++ используется для копирования данных одного объекта в другой.
// copy constructor #include using namespace std; class Base{ private: int lenght; int height; public: Base(int len, int hei){ lenght = len; height = hei; } // copy constructor Base(Base &obj){ lenght = obj.length; height = obj.height; } int display(){ return lenght * height; } }; int main(){ Base B(10,5); // copy costryctor Base b = B; cout<<b.display()<<endl; cout<<B.display()<<endl; return 0; }
Деструктор С++
- Дескруктор в С++ — это функция-член в классе, которая удаляет объект.
- Они вызываются, когда объект класса выходит за пределы области видимости, например, при завершении функции, завершении программы, удалении переменной и т. д.
- Деструктор отличается от других обычных мемер-функций тем, что он не принимает никаких аргументов и не возвращает ничего, как конструктор.
- Desctructor имеет то же имя, что и имя класса, с предшествующим знаком тильды (~).
- Деструктор вызывается автоматически, когда объекты уничтожаются или выходят за пределы области видимости.
#include<iostream> using namespace std; class Base{ private: int length; public: // constructor Base(int len){ length = len; } int getdata(){ return length * 2; } // destructor called ~Base(){ cout<<"Destructor called"<<endl; } }; int main(){ Base B(10); cout<<B.getdata()<<endl; return 0; }
Запрограммируйте на С++, создав целое число класса с печатью всех простых чисел из класса
#include<iostream> using namespace std; class Integer{ private: int n; public: void set(int n){ this->n = n; } bool isprime(int n){ if(n == 1 || n == 0)return false; for(int i = 2; i * i <= n; i++){ if(n % i == 0)return false; } return true; } void show(){ cout<<"Prime numbers are : "; for(int i = 1; i <= n; i++){ if(isprime(i)){ cout << i << " "; } } } }; int main(){ Integer i; int n; cout<<"Enter number"<<endl; cin>>n; i.set(n); i.show(); return 0; } --------------------------------------------------------------- Enter number 20 Prime numbers are : 2 3 5 7 11 13 17 19
Встроенная функция
- Встроенная функция — это функция, которая раскрывается в строке при вызове.
- Основное использование встроенной функции в C++ — экономия места в памяти. Всякий раз, когда функция вызывается, выполнение задач занимает много времени.
// Implementtation of inline function in c++ #include using namespace std; class Operation{ int a,b,add,sub,mul; public: void get(); void sum(); void diff(); void prod(); }; // inline function for get methods inline void Operation::get(){ cout<<"Enter first value"; cin>>a; cout<<"Enter second value"; cin>>b; } // inline funcion for sum methods inline void Operation::sum(){ add = a+b; cout<<"Addition is : "<<add<<endl; } // inline function for diff methods inline void Operation::diff(){ sub = a-b; cout<<"Subtraction is :"<<sub<<endl; } // inline function for prod methods inline void Operation::prod() { mul = a*b; cout<<"Multiplication is :"<<mul<<endl; } int main() { cout<<"Program using inline function"<<endl; Operation o; o.get(); o.sum(); o.diff(); o.prod(); return 0; }
Функция друга
- Сокрытие данных — фундаментальная концепция объектно-ориентированного программирования. Он ограничивает доступ приватных членов вне класса.
- Точно так же защищенные члены доступны только производным классам и недоступны извне.
- Однако в C++ есть функция, называемая дружественными функциями, которая нарушает это правило и позволяет нам получать доступ к функциям-членам извне класса.
- Функция друга может получить доступ к личным и защищенным данным класса. Мы объявляем функцию friend, используя ключевое слово friend внутри тела класса.
#include using namespace std; // Private data in class class Box{ private: int lenght; // friend function called friend int printlenght(Box); public: // initilaized lenght with 5 Box():lenght(5) {} }; // define friend function int printlenght(Box b){ // access the private data from friend function b.lenght += 10; return b.lenght; } int main(){ Box B; cout<<"Lenght of Box is :"<<printlenght(B)<<endl; return 0; }
Наследование
- Наследование — одна из ключевых особенностей объектно-ориентированного программирования на C++. Это позволяет нам создать новый класс (производный класс) из существующего класса (базового класса).
- Производный класс наследует функции базового класса и может иметь собственные дополнительные функции.
#include using namespace std; // base class class Cars{ private: string model; int price; public: void color(){ cout<<"black"<<endl; } void name(){ cout<<"Farrari"<<endl; } void speed(){ cout<<"250000KPH"<<endl; } void setModel(string m){ model = m; } string getModel(){ return model; } }; // new class(derived class) class Racing_cars : public Cars{ public: void display(string c){ cout<<c<<endl; } void design(){ cout<<"Modren"<<endl; } void milage(){ cout<<"good"<<endl; } }; // we call derived class to base class not vice versa. int main(){ Racing_cars c; c.color(); c.name(); c.speed(); c.setModel("XX1288"); c.design(); c.milage(); c.display(c.getModel()); return 0; }
Переопределение функции-члена в наследовании
- Предположим, что базовый класс и производный класс имеют функции-члены с одинаковыми именами и аргументами.
- Если мы создадим объект производного класса и попытаемся получить доступ к этой функции-члену, вместо функции в базовом классе будет вызвана функция-член в производном классе.
- Функция-член производного класса переопределяет функцию-член базового класса.
// function overriding in inheritance #include using namespace std; // base class class Base{ public: void display(){ cout<<"Base class here."<<endl; } }; // derived class and inherited class Derived : public Base{ public: void display(){ cout<<"Dericed class here."<<endl; } }; // its call only derived class not base class. int main(){ Derived D; D.display(); return 0; }
Доступ к переопределенной функции в C++
- Чтобы получить доступ к переопределенной функции базового класса, мы используем оператор разрешения области ::
- Мы также можем получить доступ к переопределенной функции, используя указатель базового класса для указания на объект производного класса, а затем вызывая функцию из этого указателя.
// function overriding in inheritance #include using namespace std; // base class class Base{ public: void display(){ cout<<"Base class here."<<endl; } }; // derived class and inherited class Derived : public Base{ public: void display(){ cout<<"Dericed class here."<<endl; // call base class function though derived class Base :: display(); } }; // its call only derived class not base class. int main(){ Derived D; D.display(); // access base class function by scode resolution operator D.Base::display(); return 0; }
Доступ к функции переопределения с помощью указателя
// function overriding in inheritance #include using namespace std; // base class class Base{ public: void display(){ cout<<"Base class here."<<endl; } }; // derived class and inherited class Derived : public Base{ public: void display(){ cout<<"Dericed class here."<<endl; } }; // its call only derived class not base class. int main(){ Derived D; // Access overiding function using pointer Base *ptr = &D; // call function of base class ptr -> display(); D.display(); return 0; }
Тип наследства
Наследование — одна из основных функций объектно-ориентированного языка программирования. Это позволяет разработчикам программного обеспечения создавать новый класс из существующего класса. Производный класс наследует функции базового класса (существующего класса).
- С++ Одиночное наследование
- Множественное наследование C++
- Многоуровневое наследование C++
- Иерархическое наследование C++
- Гибридное наследование C++
Единое наследство
- При одиночном наследовании один класс может расширять функциональность другого класса. При одиночном наследовании существует только один родительский класс и один дочерний класс.
#include<iostream> using namespace std; // Parent class class Animal { public: void eat() { cout << "eating" << endl; } }; // child class class Dog: public Animal { public: void bark() { cout << "barking"; } }; int main() { // Creating an object of the child class Dog obj; // calling methods obj.eat(); obj.bark(); return 0; }
Многоуровневое наследование
- Вы можете не только получить класс от базового класса, но вы также можете (новый) получить класс от производного класса. Эта форма наследования известна как многоуровневое наследование.
#include using namespace std; // Base class class Base{ public: void add(){ cout<<2+4<<endl; } }; // derived class which inherit from base class class Derive1 : public Base{ public: void sub(){ cout<<2-4<<endl; } }; // Derived class which inherit fron derive1 class class Derive2 : public Derive1{ public: void mul(){ cout<<2*4<<endl; } }; int main(){ Derive2 D; D.mul(); D.sub(); D.add(); return 0; }
Множественное наследование
- В программировании на C++ класс может быть производным от более чем одного родителя.
Неоднозначность множественного наследования
- Наиболее очевидная проблема с множественным наследованием возникает во время переопределения функции.
- Предположим, два базовых класса имеют одну и ту же функцию, которая не переопределяется в производном классе.
- Затем используйте оператор разрешения области действия, чтобы получить к нему доступ.
#include using namespace std; // base class 1 class Base_1{ public: void display(){ cout<<"This is Base class 1."<<endl; } }; // Base class 2 class Base_2{ public: void display(){ cout<<"This is Base class 2."<<endl; } }; // derive class which inherit though Base 1 class and also Base class 2 class Derive : public Base_1, public Base_2{ public: void display(){ cout<<"This is Derived class."<<endl; } }; int main(){ Derive D; D.display(); // function overidding -> to access use scope resolution opeartor D.Base_1 :: display(); D.Base_2 :: display(); return 0; }
Иерархическое наследование C++
- Если от базового класса наследуется более одного класса, это называется иерархическим наследованием. При иерархическом наследовании все функции, общие для дочерних классов, включаются в базовый класс.
- Например, физика, химия, биология являются производными от класса естественных наук.
#include using namespace std; // Base class class Science{ public: void display(){ cout<<"Belong to Science Class."<<endl; } }; // Derive class which inherit though science class class Physics : public Science{ public: void display(){ cout<<"this is Physics class."<<endl; } }; // Derive class which inherit though science class class Biology : public Science{ public: void display(){ cout<<"this is biology class."<<endl; } }; // Derive class which inherit though science class class Chemistry : public Science{ public: void display(){ cout<<"this is Chemistry class."<<endl; } }; int main(){ Physics Ph; Ph.display(); Ph.Science :: display(); Biology B; B.display(); B.Science :: display(); Chemistry ch; ch.display(); ch.Science :: display(); return 0; }
Гибридное наследование C++
- Гибридное наследование представляет собой комбинацию нескольких типов наследования. Например, отношения дочернего и родительского классов, которые следуют множественному и иерархическому наследованию, можно назвать гибридным наследованием.
#include <iostream> using namespace std; // Parent class1 class Vehicle { public: Vehicle() { cout << "This is a Vehicle" << endl; } }; //Parent class2 class Fare { public: Fare() { cout << "Fare of Vehicle\n"; } }; //Child class1 class Car: public Vehicle { }; //Child class2 class Bus: public Vehicle, public Fare { }; int main() { // creating object of sub class will // invoke the constructor of base class Bus obj2; return 0; }
Полиморфизм
- Полиморфизм — важная концепция объектно-ориентированного программирования. Это просто означает более одной формы или много форм. То есть один и тот же объект (функция или оператор) ведет себя по-разному в разных сценариях. Например,
- Оператор + в C++ используется для выполнения двух определенных функций. Когда он используется с числами (целыми числами и числами с плавающей запятой), он выполняет сложение
int a = 5; int b = 6; int sum = a + b; // sum = 11
и Однако + также используется для объединения двух строковых операндов.
string firstName = "abc "; string lastName = "xyz"; // name = "abc xyz" string name = firstName + lastName;
Мы можем реализовать полиморфизм в C++ следующими способами:
- Перегрузка функций
- Перегрузка оператора
- Переопределение функции
- Виртуальные функции
Типы полиморфизмов
- Полиморфизм времени выполнения
- Пломорфизм времени компиляции
Полиморфизм времени компиляции
- Этот тип полиморфизма достигается за счет перегрузки функций и перегрузки операторов.
- Он также известен как "статический" или "раннее связывание".
Почему это называется полиморфизмом времени компиляции?
- Перегруженные функции вызываются путем сравнения типов данных и количества параметров. Этот тип информации доступен компилятору во время компиляции. Таким образом, подходящая функция для вызова будет выбрана компилятором C++ во время компиляции.
Перегрузка функций
- мы можем использовать две функции с одинаковым именем, если они имеют разные параметры (либо типы, либо количество аргументов).
Перегрузка функций может быть достигнута в следующих двух случаях:
- Имена функций и типы возвращаемых значений совпадают, но различаются типом аргументов.
#include<iostream> using namespace std; class Base{ private: int x = 10; double x1 = 10.1; public: void add(int y){ cout << "Value of x + y is: " << x + y << endl; } // Differ in the type of argument. void add(double d){ cout << "Value of x1+d is: " << x1 + d << endl; } }; int main(){ Base b; b.add(5); b.add(5.3); return 0; }
- Имена функций и типы возвращаемых значений одинаковы, но различаются количеством аргументов.
#include<iostream> using namespace std; class Base{ private: int x = 10; double x1 = 10.1; public: void add(int y){ cout << "Value of x + y is: " << x + y << endl; } // Differ in the number of argument. void add(int y, double d){ cout << "Value of x1+d is: " << y + d << endl; } }; int main(){ Base b; b.add(5); b.add(5,5.3); return 0; }
- Перегруженные функции вызываются путем сопоставления типа и количества аргументов. Поскольку эта информация доступна на во время компиляции, компилятор выбирает правильную функцию на основе ее параметров.
Перегрузка оператора
- В C++ мы можем перегружать оператор, пока работаем с пользовательскими типами, такими как объекты или структуры.
- Перегрузка операторов — это в основном перегрузка функций, когда разные операторные функции имеют один и тот же символ, но разные операнды.
Note: -> A user-defined type must be present in at least one operand. -> ".", "::", typeid, size, ".*", and C++'s single ternary operator, "?:", are among the operators that cannot be overloaded. These are some of the operators that can be overloaded in C++ : Arithmetic operators : - , + , / , * , % and -=, +=, /= , *= , %= Boolean algebra : !=, ==, > ,< ,>=, <= , && ,|| Bit manipulation : &, |, ^ ,<< ,>> and |=, &= ,>>=, <<=, ^= Memory management : new[], new, delete[], delete // C++ program to unary overload ++ when used as prefix #include <iostream> using namespace std; class Count { private: int value; public: // Constructor to initialize count to 0 Count() : value(0) {} // Overload ++ when used as prefix void operator ++() { value = value + 1; } void display() { cout << "Count: " << value << endl; } }; int main() { Count count1; // Call the "void operator ++(object)" function ++count1; count1.display(); return 0; } Before using ++ operator: 0 After using ++ operator: 1
Полиморфизм во время выполнения
- Полиморфизм времени выполнения возникает, когда функции разрешаются во время выполнения, а не во время компиляции, когда вызов переопределенного метода разрешается динамически во время выполнения, а не во время компиляции.
- Он также известен как поздняя привязка или динамическая привязка.
- Полиморфизм во время выполнения достигается за счет сочетания переопределения функций и виртуальных функций.
Переопределение функции
- В C++ Inheritance у нас может быть одна и та же функция как в базовом классе, так и в его производных классах. Ранее мы обсуждали переопределение функций-членов при наследовании.
// function overriding in inheritance #include using namespace std; // base class class Base{ public: void display(){ cout<<"Base class here."<<endl; } }; // derived class and inherited class Derived : public Base{ public: void display(){ cout<<"Derived class here."<<endl; } }; // its call only derived class not base class. int main(){ Derived D; D.display(); // for access use scope of resolution D.base :: display(); // Access overiding function using pointer Base *ptr = &D; // call function of base class ptr -> display(); return 0; }
- Это полиморфизм времени выполнения, потому что вызов функции не разрешается компилятором, а вместо этого разрешается во время выполнения.
Перегрузка оператора с помощью функции друга
- Это обеспечивает большую эффективность и гибкость класса. Эта функция не является членом класса и не имеет указателя this.
Note: -> The this pointer in C++ stores the address of the class instance (object) which is called from the member function, to enable functions to access the correct object data members. -> (To Know more Read article here....)
- при перегрузке унарного (++,- -) оператора вы должны передать один аргумент.
- при перегрузке бинарного (+,-) оператора у вас есть два аргумента.
// Operating overoading using friend function #include <iostream> using namespace std; class Complex{ private: int real; int img; public: // Default Constructor Complex (int r = 0, int i = 0){ real = r; img = i; } void Display (){ cout << real << "+i" << img; } // Friend Function with binary operator override and pass objects as arguments friend Complex operator + (Complex c1, Complex c2); }; // Defination of friend function Complex operator + (Complex c1, Complex c2){ Complex temp; temp.real = c1.real + c2.real; temp.img = c1.img + c2.img; return temp; } int main (){ Complex C1(5, 3), C2(10, 5), C3; C1.Display(); cout << " + "; C2.Display(); cout << " = "; C3 = C1 + C2; C3.Display(); } // C1 => 5+i3 // C2 => 10+i5 // C3 => 15+i8 (Result)
Виртуальная функция
- Виртуальная функция — это функция-член в базовом классе, которую мы ожидаем переопределить в производных классах.
- По сути, виртуальная функция используется в базовом классе для обеспечения того, что функция переопределена. Это особенно относится к случаям, когда указатель базового класса указывает на объект производного класса.
#include <iostream> using namespace std; class Base { public: virtual void print() { cout << "Base Function" << endl; } }; class Derived : public Base { public: void print() { cout << "Derived Function" << endl; } }; int main() { Derived derived1; // pointer of Base type that points to derived1 Base* base1 = &derived1; // calls member function of Derived class base1->print(); return 0; } // Output => Derived Function
- используя виртуальную функцию, мы получаем доступ к данным производного класса из базового класса.
// C++ program to demonstrate the use of virtual function #include <iostream> #include <string> using namespace std; class Animal { private: string type; public: // constructor to initialize type Animal() : type("Animal") {} // declare virtual function virtual string getType() { return type; } }; class Dog : public Animal { private: string type; public: // constructor to initialize type Dog() : type("Dog") {} string getType() override { return type; } }; class Cat : public Animal { private: string type; public: // constructor to initialize type Cat() : type("Cat") {} string getType() override { return type; } }; void print(Animal* ani) { cout << "Animal: " << ani->getType() << endl; } int main() { // Dynamically create using animal pointer Animal* animal1 = new Animal(); Animal* dog1 = new Dog(); Animal* cat1 = new Cat(); print(animal1); print(dog1); print(cat1); return 0; }
Виртуальный базовый класс
- виртуальный базовый класс используется в виртуальном наследовании для предотвращения создания нескольких экземпляров данного класса появляется в иерархии наследования при использовании множественного наследования.
- Виртуальный базовый класс в C++ — это функция-член базового класса, которую вы переопределяете в производном классе. Интерактивное ключевое слово используется для его объявления.
- Он сообщает компилятору, должна ли функция быть связана динамически или с поздней привязкой.
- Данные-члены/функциикласса Base дважды наследуются классом D, как показано на диаграмме. Первый проведет вас через класс B, а второй проведет вас через класс C. Когда объект класса D обращается к любому элементу данных или функции класса Base, неясно, какой элемент данных или функции будет назван. Один был унаследован через B, а другой — через C. Это зацикливает компилятор и вызывает ошибку.
#include <iostream> using namespace std; class Base{ public: int a; // contructor Base(){ a = 10; } }; class B : public virtual Base{ }; class C : public virtual Base{ }; class D : public B, public Base{ }; int main() { D object; cout << "a = " << object.a << endl; return 0; }
Виртуальная функция VS чистая виртуальная функция
Заключение
- c++ — это простой, статический, скомпилированный, универсальный, высокоуровневый, объектно-ориентированный язык программирования.
- Конструктор — это специальный тип функции-члена, который вызывается автоматически при создании объекта.
- Тип конструктора: — конструктор по умолчанию, параметризованный и копирующий.
- Встроенная функция — это функция, которая раскрывается в строке при вызове.
- Функция друга может получить доступ к закрытым и защищенным данным класса. Мы объявляем функцию friend, используя ключевое слово friend внутри тела класса.
- Наследование — одна из ключевых особенностей объектно-ориентированного программирования на C++. Это позволяет нам создать новый класс (производный класс) из существующего класса (базового класса).
- Переопределение функций: базовый класс и производный класс имеют функции-члены с одинаковыми именами и аргументами.
- Чтобы получить доступ к переопределенной функции базового класса, мы используем оператор разрешения области видимости : : & с помощью указателя.
- Тип наследования: множественное, многоуровневое и иерархическое наследование.
- Перегрузка функций: мы можем использовать две функции с одинаковыми именами, если они имеют разные параметры (либо типы, либо количество аргументов).
- полиморфизм означает, что вызов функции-члена приведет к выполнению другой функции в зависимости от типа объекта, который вызывает функцию.
- Тип полиморфизма: полиморфизм времени выполнения и времени компиляции.
- Виртуальная функция — это функция-член в базовом классе, которую мы ожидаем переопределить в производных классах.
- виртуальный базовый класс используется в виртуальном наследовании для предотвращения создания нескольких экземпляров данного класса появляется в иерархии наследования при использовании множественного наследования.