领悟面向对象就离开发应用不远了(类提高)有你对面向对象的所有疑问,爆肝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 } ``` # 最后 还是原创不易,欢迎三连
相关文章
|
算法 程序员 API
C 语言和 C++ 有什么区别?老程序员居然这样理解,不怕你不懂
C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制)
152 0
|
5月前
|
Java
Java面向对象编程新篇章:多态,你准备好了吗?
【6月更文挑战第17天】Java的多态性是面向对象编程的核心,它允许通过统一的接口处理不同类型的对象。例如,在一个虚拟宠物游戏中,抽象类`Pet`定义了`speak()`方法,猫、狗和鹦鹉等子类各自重写此方法以实现独特叫声。在`main`方法中,使用`Pet`类型的引用创建子类对象并调用`speak()`,多态机制确保调用实际对象的方法,实现代码的灵活性和可扩展性。通过多态,我们能以更低的耦合度和更高的复用性编写更优雅的代码。
36 3
|
3月前
|
敏捷开发 设计模式 测试技术
代码之禅:从技术实践中领悟软件开发的本质
【7月更文挑战第41天】 在数字世界的浪潮中,软件开发已成为一门艺术与科学交织的领域。本文将探讨从实际技术实践中提炼出的软件构建哲学,揭示编程背后隐藏的智慧与策略。我们将通过一系列真实案例分析,探索如何提升代码质量、优化开发流程,并讨论持续学习的重要性。文章旨在为开发者提供深入洞见,帮助他们在不断变化的技术环境中保持竞争力和创新精神。
|
3月前
|
存储 开发者 Ruby
【揭秘Ruby高手秘籍】OOP编程精髓全解析:玩转类、继承与多态,成就编程大师之路!
【8月更文挑战第31天】面向对象编程(OOP)是通过“对象”来设计软件的编程范式。Ruby作为一种纯面向对象的语言,几乎所有事物都是对象。本文通过具体代码示例介绍了Ruby中OOP的核心概念,包括类与对象、继承、封装、多态及模块混合,展示了如何利用这些技术更好地组织和扩展代码。例如,通过定义类、继承关系及私有方法,可以创建具有特定行为的对象,并实现灵活的方法重写和功能扩展。掌握这些概念有助于提升代码质量和可维护性。
34 0
|
6月前
|
程序员 Python
类的设计奥秘:从代码到架构的科普全解
类的设计奥秘:从代码到架构的科普全解
92 2
|
6月前
|
Java C++ Python
编程的奇妙世界:膛目结舌的代码技巧探秘
编程的奇妙世界:膛目结舌的代码技巧探秘
|
安全 编译器 网络安全
一些碎碎念以及类和对象零碎知识点补充
一些碎碎念以及类和对象零碎知识点补充
104 0
一些碎碎念以及类和对象零碎知识点补充
|
JavaScript 前端开发 API
【重温基础】14.元编程
【重温基础】14.元编程
249 0
|
Java 开发者 设计模式
接口的魅力:全能的世界蓝图 | 带你学《Java面向对象编程》之五十九
本节旨在为读者展现接口的全能性与其独有的功能:制定标准。
接口的魅力:全能的世界蓝图   | 带你学《Java面向对象编程》之五十九
|
设计模式 Java
掌握接口,从这三则案例开始! | 带你学《Java面向对象编程》之六十二
本节手把手带着读者借助接口和工厂设计模式完成获取类信息、处理绘图、设计图形类三则案例。
掌握接口,从这三则案例开始!  | 带你学《Java面向对象编程》之六十二