C/C++ 面向对象编程,面向对象设计(OOP,OOD)
2021/10/1 20:11:42
本文主要是介绍C/C++ 面向对象编程,面向对象设计(OOP,OOD),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 前言
- Object Based
- Class without pointer member(不带指针)
- Class with pointer member(带指针)
- Object Oriented
- class之间的关系
- Composition(复合)
- Delegation(委托)
- Inheritance(继承)
- class之间的关系组合
- Inheritance (继承) with virtual functions (虚函数)
- Inheritance(继承)+ Composition(复合)
- Delegation (委托) + Inheritance (继承)
前言
我们知道想要学习面向对象编程or设计,首先,我们要先掌握一门语言,这里我们以C++语言为主。
这里,我们把其分为两部分:
- Object Based:面向单一class的设计
- Object Oriented:面向多重class设计,class与class之间的关系
Object Based
其中单一class有两个经典分类:
Class without pointer member(不带指针)
- 不带指针的类,类似于C语言中的struct,但其可以包含成员函数等。
Class with pointer member(带指针)
- 在带指针的类中,因为包含指针,为了防止内存泄漏,必须有拷贝构造(copy ctor)和拷贝赋值(copy op =)。
- new和delete分配动态空间在 堆(heap)中,而正常构造出来的对象是存放在 栈(stack)中。
由于这部分内容繁多,不再赘述,主要介绍一下class与class之间的关系。
Object Oriented
class之间的关系
Composition(复合)
复合,表示的是一种包含的关系(has a)。
类似于C++中的容器,queue和deque。其中23种设计模式中-适配器模式就是采用这种思想。部分代码如下:
template <class T> class queue { ... protected: deque<T> c; // 底层容器 public: // 以下完全利用 c 的操作函数完成 bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference front() { return c.front(); } reference back() { return c.back(); } // void push(const value_type& x) { c.push_back(x); } void pop() { c.pop_front(); } };
从内存占用上来看:
其中,复合关系下的构造和析构函数有如下关系:
- 构造函数时由内向外,Container 的构造函数首先调用 Component 的 default 构造函数,然后才执行自己。
- 析构函数是由外向内,Container 的析构函数首先执行自己,然后才调用 Component 的析构函数。
Delegation(委托)
Composition by reference。我个人理解委托也是复合一种,一个class中包含了另一种class中的指针。只是在学术术语上有所区别。
可以参考下面代码:
** String.h **
class StringRep; class String { public: String(); String(const char* s); String(const String& s); String &operator=(const String& s); ~String(); private: StringRep* rep; // pimpl };
** String.cpp **
#include "String.hpp" namespace { class StringRep { friend class String; StringRep(const char* s); ~StringRep(); int count; char* rep; }; } String::String(){ ... }
其关系图如图所示:
创建三个String对象a、b、c,共同指向了同一块地址,如果其中一个对象a想要修改其中内容,会单独复制出一份来进行修改。
Inheritance(继承)
继承,表示的是一种属于关系( is a )。
部分代码如下:
class_List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; }; template<typename _Tp> struct _List_node : public _List_node_base { _Tp _M_data; };
示意图如下:
继承下的构造、析构函数有如下关系:
其中,基类的析构函数必须是virtual,否则会出现内存泄漏等未知行为。
- 构造由内而外,Derived 的构造函数首先调用 Base 的 default 构造函数,然后才执行自己。
- 析构由外而内,Derived 的析构函数首先执行自己,然后才调用 Base 的析构函数。
class之间的关系组合
Inheritance (继承) with virtual functions (虚函数)
class类中virtual函数有三种:
- non-virtual 函数:不希望derived class重新定义。
- virtual 函数:希望derived class 重新定义,而且已经有了默认定义。
- pure virtual 函数:希望derived class 一定重新定义,并且没有默认定义。
其中模板方法模式中用到了这种面向对象设计:
Inheritance(继承)+ Composition(复合)
这种情况下,构造函数是由内向外的,Derived的构造函数先调用Base的默认构造函数,然后调用Component的默认构造函数,然后才执行自己。析构函数是由外向内,Derived的析构函数首先执行自己,然后调用Component的析构函数,最后调用Base的析构函数。
这种情况下,构造函数是由内向外的,析构函数是由外向内。由图可以较容易看出。
Delegation (委托) + Inheritance (继承)
这是最常见的一种组合方式,其中观察者模式、组合模式、原型模式就是由这种设计。
观察者模式
组合模式
原型模式
这篇关于C/C++ 面向对象编程,面向对象设计(OOP,OOD)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-08CCPM如何缩短项目周期并降低风险?
- 2025-01-08Omnivore 替代品 Readeck 安装与使用教程
- 2025-01-07Cursor 收费太贵?3分钟教你接入超低价 DeepSeek-V3,代码质量逼近 Claude 3.5
- 2025-01-06PingCAP 连续两年入选 Gartner 云数据库管理系统魔力象限“荣誉提及”
- 2025-01-05Easysearch 可搜索快照功能,看这篇就够了
- 2025-01-04BOT+EPC模式在基础设施项目中的应用与优势
- 2025-01-03用LangChain构建会检索和搜索的智能聊天机器人指南
- 2025-01-03图像文字理解,OCR、大模型还是多模态模型?PalliGema2在QLoRA技术上的微调与应用
- 2025-01-03混合搜索:用LanceDB实现语义和关键词结合的搜索技术(应用于实际项目)
- 2025-01-03停止思考数据管道,开始构建数据平台:介绍Analytics Engineering Framework