领悟面向对象就离开发应用不远了(类提高)有你对面向对象的所有疑问,爆肝1w字

简介: 领悟面向对象就离开发应用不远了(类提高)有你对面向对象的所有疑问,爆肝1w字

@TOC


# 前言 hello,码神又回来了,首先感谢大家对上篇类的支持,其次就是来还欠下的面向对象了,秋名山路途漫漫,码神始终与你们同在,发车了! # 一、面向对象 实际上面向对象是一个范指的概念,其中面向对象一般来说就是代指其中的类,这也是我上一篇为什么写写了一下类的原因,使用好了类,真的就领悟了面向对象。 # 二、使用类 ## 1.类的基础使用 大致就是我上篇博客所写,这篇我们就注重于提高,[当我学会了类,就离领悟面向对象编程不远了(基础)!!](https://blog.csdn.net/weixin_45920495/article/details/119831064?spm=1001.2014.3001.5501) ## 2.运算符重载 首先我们明确一点,运算符重载是c++多态的一种形式,我们来类比与函数重载来看:**同名的函数来完成相同的基本操作**,即使被利用与不同的数据类型,运算符重载也差不多 例如:**运算符“ * ”一样在指针中用来解引用,但是它还是乘法运算符** 再看如何定义一个**自己的重载运算符** *operator+()重载+运算符* ```cpp 返回值类型 operator 运算符(形参表) { .... } ``` 实例: ```cpp #include using namespace std; class Complex { public: double real, imag; Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) { } Complex operator - (const Complex & c); }; Complex operator + (const Complex & a, const Complex & b)//+重载 { return Complex(a.real + b.real, a.imag + b.imag); //返回一个临时对象 } Complex Complex::operator - (const Complex & c) { return Complex(real - c.real, imag - c.imag); //返回一个临时对象 } int main() { Complex a(4, 4), b(1, 1), c; c = a + b; //等价于 c = operator + (a,b); cout << c.real << "," << c.imag << endl; cout << (a - b).real << "," << (a - b).imag << endl; //a-b等价于a.operator - (b) return 0; } ``` 可以重载的太多了,简单就用+带过了。 意义:如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算,**运用与对象处理** ## 3.友元 怎么说这个呢?平常不用,但是有一种地方用了**更好**:**公有类方法提供了唯一的访问途径,但是有时候不太适用于特定的问题**,友元就出现了 ### 1.友元函数 可以看为类的扩展接口,直接用吧: ```cpp //创建友元函数是将其放入类声明中 class A { friend a operator*(double m, const T &t) } ``` 有一下俩点值得注意的: 1. 虽然operator*()是在类中声明的,但是不是成员函数,所以不能用成员运算符来调用 2. 不是成员函数,但是与成员函数的访问权限相同 函数主体也有些不同,不能用::作用域 ```cpp a operator*(double m,const T &t) { //主体随意 } ``` ### 2.友元类 友元类的**所有成员函数都是另一个类的友元函数**,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。 当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下: friend class 类名; ```cpp #include using namespace std; class B { private: int tt; friend class A;//相当于a为b的友元类,a可以使用b的数据 friend void Show( A& , B& ); public: B( int temp = 100):tt ( temp ){} }; class A { private: int value; friend void Show( A& , B& ); public: A(int temp = 200 ):value ( temp ){} void Show( B &b ) { cout << value << endl; cout << b.tt << endl; } }; void Show( A& a, B& b ) { cout << a.value << endl; cout << b .tt << endl; } int main() { A a; B b; a.Show( b ); Show( a, b ); return 0; } ``` 相当于**破坏了c++中封装数据的特性**,所以一般也不用 ### 3.友元成员函数 **友元成员函数声明和定义的顺序必须满足一定要求** ```cpp #include #include using namespace std; class Person; //声明 class Student { public: void ShowInf(Person& PersonObject); }; class Person { friend void Student::ShowInf(Person& PersonObject); private: int age; string name; public: Person(string name, int age) { this->name = name; this->age = age; } Person(Person& PersonObject) { this->name = PersonObject.name; this->age = PersonObject.age; } Person operator = (Person PersonObject) { this->age = PersonObject.age; this->name = PersonObject.name; } }; void Student::ShowInf(Person& PersonObject) { cout << PersonObject.name << "的年龄为" << PersonObject.age << endl; } int main() { Person PersonObject("张三", 19); Student StudentObject; StudentObject.ShowInf(PersonObject); } ``` **用Student类中的ShowInf()成员函数访问Person类中的私有成员name和age** # 三、类继承 好了开始下一个重点继承,内容有点多,建议收藏 继承什么,像二代一样,儿子继承父亲,这里的基类就像父亲,派生类好比于儿子。 在好比于我们用的数据库,一般来说现成的数据库不容许个人修改,但是为了提高重用性,C++提供了类继承来实现扩展类和修改类,就像继承一笔财产肯定比白手起家要快的多,类的继承有2个概念: ## 基类 我们这里用国乒来举例子,还是刘国梁的队伍,但是这次由于训练人数变多,球桌不够用了,下面看代码 ```cpp #include #include using namespace std; class TableTennisPlayer //记录是否有球桌,及名字 { private: string firstname; string lastname; bool hasTable; public: TableTennisPlater(const string & fn="none",const string &ln="none",bool ht=flase); coid Name() const; bool HasTable() const{return hasTable;}; void ReseTable(bool v) {hasTable =v ;}; } TableTennisPlayer :: TableTennisPlayer (const string &fn,const string &ln,bool ht):firstname(fn),lastname(ln),hasTable(ht) {}//构造函数 void TableTennisPlayer::Name() const { cout< using namespace std; class Fish { public: // define a pure virtual function Swim virtual void Swim() = 0; }; class Tuna :public Fish { public: void Swim() { cout << "Tuna swims fast in the sea! " << endl; } }; class Carp :public Fish { void Swim() { cout << "Carp swims slow in the lake!" << endl; } }; void MakeFishSwim(Fish& inputFish) { inputFish.Swim(); } int main() { // Fish myFish; // Fails, cannot instantiate an ABC Carp myLunch; Tuna myDinner; MakeFishSwim(myLunch); MakeFishSwim(myDinner); return 0; } ``` main( )的第 1 行被注释掉了, **原因是**它表明, 编译器不允许您创建抽象基类( ABC)Fish 的实例。编译器要求您创建具体类(如 Tuna)的对象,这与现实世界一致。第 7 行声明了纯虚函数 Fish::Swim( ),这迫使 Tuna 和 Carp 必须分别实现 Tuna::Swim( )和 Carp::Swim( )。第 27~30 行实现了 MakeFishSwim(Fish&),这表明虽然不能实例化抽象基类,但可将指针或引用的类型指定为抽象基类。抽象基类提供了一种非常好的机制,让您能够声明所有派生类都必须实现的函数。如果 Trout 类从Fish 类派生而来,但没有实现 Trout::Swim( ),将无法通过编译。 抽象基类常被简称为 ABC。 ## 4.动态与静态的联编 联编:将源代码中的函数调用解释为执行特定的函数代码块被称为函数名联编,因为有个**函数重载**,所以还比较复杂,此刻的编译器查看参数及函数名,在编译过程中的联编称为**静态联编**,当出现虚函数时,过程更加复杂,编译器必须生成能够在程序运行时选择的正确的虚方法的代码,这又 称为**动态联编** ### 静态 静态联编对函数的选择是基于指向对象的指针或者引用的类型。其优点是效率高,但灵活性差。 ```cpp #include class A {public: voidf() {cout<<"A"<<"";} }; classB:publicA {public: void f() {cout<<"B"<f(); pa=&b;pa->f(); //结果为A A } ``` 程序的运行结果可以看出,通过对象指针进行的普通成员函数的调用,仅仅与指针的类型有关,而与此刻指针正指向什么对象无关。要想实现当指针指向不同对象时执行不同的操作,就必须将基类中相应的成员函数定义为虚函数,进行动态联编。 ### 动态 动态联编对成员函数的选择是基于对象的类型,针对不同的对象类型将做出不同的编译结果。C++中一般情况下的联编是静态联编,但是当涉及到多态性和虚函数时应该使用动态联编。**动态联编的优点是灵活性强,但效率低。** 值得注意的是 只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式为:指向基类的指针变量名->虚函数名(实参表)或基类对象的引用名.虚函数名(实参表) 实现动态联编需要同时满足以下三个条件: ① 必须把动态联编的行为定义为类的虚函数。 ② 类之间应满足子类型关系,通常表现为一个类从另一个类公有派生而来。 ③ 必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。 ```cpp #include classA { public: Virtual voidf()//虚函数 {cout<<"A"<<"";}}; classB:publicA { public: Virtual voidf()//虚函数 { cout<<"B"<f(); pa=&b; pa->f(); //结果为A B } ``` # 最后 还是原创不易,欢迎三连
相关文章
|
Java
编程中最难的就是命名?这几招教你快速上手(4)
编程中最难的就是命名?这几招教你快速上手
84 0
编程中最难的就是命名?这几招教你快速上手(4)
|
6月前
|
设计模式 编译器 C++
【C++航海王:追寻罗杰的编程之路】特殊类的设计方式你知道哪些?
【C++航海王:追寻罗杰的编程之路】特殊类的设计方式你知道哪些?
31 0
|
Java 程序员 编译器
编程中最难的就是命名?这几招教你快速上手(1)
编程中最难的就是命名?这几招教你快速上手(1)
86 0
编程中最难的就是命名?这几招教你快速上手(1)
编程中最难的就是命名?这几招教你快速上手(2)
编程中最难的就是命名?这几招教你快速上手
51 0
编程中最难的就是命名?这几招教你快速上手(2)
|
Java 程序员 开发者
优秀程序员的学习习惯和方法你都不知道,还学什么编程
好的学习习惯和方法会让你的工作事半功倍,快来看看你还差哪些
75 0
优秀程序员的学习习惯和方法你都不知道,还学什么编程
|
关系型数据库
编程中最难的就是命名?这几招教你快速上手(3)
编程中最难的就是命名?这几招教你快速上手
58 0
|
Java 关系型数据库 程序员
编程中最难的就是命名?这几招教你快速上手
编程中最难的就是命名?这几招教你快速上手
733 14
|
安全 Java 编译器
Java面向对象编程·下
Java面向对象编程·下
81 0
|
存储 Java 数据库
Java面向对象编程·上
Java面向对象编程·上
67 0
|
小程序 数据安全/隐私保护 C语言
爱上c++的第九天-聊一聊类和对象的特性
总结如下:1.基于过程的程序设计:由一个个函数组成,每个函数都是独立的,一个函数对应一个操作,适合小程序开发。讲究每一步都要详细的写出,写出来,问题也就解决了。
66 0
爱上c++的第九天-聊一聊类和对象的特性