首页 > 设计模式 之美 -- 面向对象(C/C++分别实现)

设计模式 之美 -- 面向对象(C/C++分别实现)

文章目录

      • 前言
      • 封装
        • C++实现
        • C 实现
      • 继承
        • C++ 实现
        • C实现

前言

为了保证代码的可复用性、可扩展性、可维护性,我们提出了面向对象的思想。

面向对象的核心特性有以下几个

  • 封装特性

    信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式来访问内部信息或者数据。

    封装用来提升代码的可扩展性、可维护性
  • 继承特性

    继承是用来表示类之间的 is-a 关系,分为两种模式:单继承和多继承。单继承表示一个子类只继承一个父类,多继承表示一个子类可以继承多个父类。为了实现继承这个特性,编程语言需要提供特殊的语法机制来支持。继承主要是用来解决代码可复用性的问题
  • 多态特性

    多态是指子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。

    多态可以提高代码的可扩展性和可复用性

C++提供语法来实现以上三个特性,而C语言则可以使用函数指针来实现以上三个特性。

封装

C++实现

class Person{ 
private:char *pFName;char *pLName;
public:Person(const char * const str1,const char * const str2):pFName(str1),pLNname(str2){ }~Person();void Person_DisplayInfo();void Person_WriteToFile(const char* pFileName);
}void Person::Person_DisplayInfo()
{ cout <<"pFName is " << this->pFName<< endl;cout <<"pLName is " << this -> pLName << endl;
}void Person::Person_WriteToFile(const char* pFileName)
{ if(!pFileName) { cout <<"file name is null" << endl;return;}FILE *fp;printf("write ot file name is: %s
",pFileName);fp = fopen(pFileName, "a+");char *buff = NULL;buff = (char *)malloc(sizeof(DATA_SIZE));if(!buff) { printf("malloc failed
");return;}int count;strcpy(buff,this->pFName);count = fwrite(buff,sizeof(char),strlen(buff),fp);printf("write to %s's result is %d 
",pFileName,count);fclose(fp);fp = NULL;
}int main()
{ Person obj("lili","chuchu");obj.Person_DisplayInfo();obj.Person_WriteToFile("test.txt");return 0;
}

C 实现

person.h

#include 
#include typedef struct _Person Person;//declaration of pointers to functions
typedef void    (*fptrDisplayInfo)(Person*);
typedef void    (*fptrWriteToFile)( Person*, const char*);
typedef void    (*fptrDelete)( Person *) ;typedef struct _Person { char* pFName;char* pLName;//interface for functionfptrDisplayInfo   Display;fptrWriteToFile   WriteToFile;fptrDelete      Delete;
}Person;Person* new_Person(const char* const pFirstName, const char* const pLastName); //constructorvoid delete_Person(Person* const pPersonObj);    //destructorvoid Person_DisplayInfo(Person* const pPersonObj);
void Person_WriteToFile(Person* const pPersonObj, const char* pFileName);

person.c

#include 
#include 
#include "person.h"#define DATA_SIZE 1024 Person* new_person(const char* const pFirstName, const char* const pLastName)
{ Person *obj = NULL;obj = (Person *)malloc(sizeof(Person));if(!obj){ return NULL;}obj -> pFName =  malloc(sizeof(char)*(strlen(pFirstName)+1));if(!obj -> pFName) { return NULL;}strcpy(obj -> pFName, pFirstName);obj -> pLName = malloc(sizeof(char) * (strlen(pLastName) + 1));if(!obj -> pLName) { return NULL;}strcpy(obj -> pLName, pLastName);/*construct the function pointer*/obj->Delete = delete_Person;obj->Display = Person_DisplayInfo;obj->WriteToFile = Person_WriteToFile;printf("finish constructor Person
");return obj;
}void Person_WriteToFile(Person* const pPersonObj, const char* pFileName)
{ if(!pPersonObj || !pFileName) { return;}FILE *fp;printf("write ot file name is: %s
",pFileName);fp = fopen(pFileName, "a+");char *buff = NULL;buff = (char *)malloc(sizeof(DATA_SIZE));if(!buff) { printf("malloc failed
");return;}int count;strcpy(buff,pPersonObj->pFName);count = fwrite(buff,sizeof(char),strlen(buff),fp);printf("write to %s's result is %d 
",pFileName,count);fclose(fp);fp = NULL;
}void delete_Person(Person* const pPersonObj)
{ if(!pPersonObj) { return;}if(pPersonObj -> pFName) { free(pPersonObj->pFName);pPersonObj -> pFName = NULL;}if(pPersonObj -> pLName) { free(pPersonObj -> pLName);pPersonObj -> pLName = NULL;}}void Person_DisplayInfo(Person* const pPersonObj) { if(!pPersonObj) { printf("obj is not exists, please construct
");}printf("pFName is %s
",pPersonObj -> pFName);printf("pLName is %s
",pPersonObj -> pLName);
}

main.c

#include 
#include 
#include "person.h"
//#include "employee.h"int main(int argc, char *argv[]) { Person *obj;obj = new_person("pfirst_name","plast_name");obj -> Display(obj);obj -> WriteToFile(obj,"F:\test_write.txt");obj -> Delete(obj);return 0;
}

继承

C++ 实现

class Person{ 
private:char *pFName;char *pLName;
public:Person(const char * const str1,const char * const str2):pFName(str1),pLNname(str2){ }~Person(){ }void Person_DisplayInfo();void Person_WriteToFile(const char* pFileName);
}class Empolyee:public Person{ 
private:char* pDepartment;char* pCompany;int nSalary;
public:Empolyee(const char * const str1,const char * conststr2,int num):Person(str1,str2),pDepartment(str1),pCompany(str2),nSalary(num){ }~Empolyee(){ }void Employee_DisplayInfo();
}
void Empolyee::Employee_DisplayInfo()
{ Person_DisplayInfo();//可以访问基类的公有成员cout << "pDepartment is " << pDepartment << endl;cout << "pCompany is " << pCompany<< endl;cout << "nSalary is " << nSalary << endl;
}

C实现

person.c如上,person.h增加万能指针void *

person.h

#include 
#include /* run this program using the console pauser or add your own getch, system("pause") or input loop */typedef struct _Person Person;//declaration of pointers to functions
typedef void    (*fptrDisplayInfo)(Person*);
typedef void    (*fptrWriteToFile)( Person*, const char*);
typedef void    (*fptrDelete)( Person *) ;typedef struct _Person { void *pDerivedObj; char* pFName;char* pLName;//interface for functionfptrDisplayInfo   Display;fptrWriteToFile   WriteToFile;fptrDelete      Delete;
}Person;Person* new_Person(const char* const pFirstName, const char* const pLastName); //constructorvoid delete_Person(Person* const pPersonObj);    //destructorvoid Person_DisplayInfo(Person* const pPersonObj);
void Person_WriteToFile(Person* const pPersonObj, const char* pFileName);

employee.h

#include "Person.h"typedef struct _Employee Employee;typedef struct _Employee
{ Person* pBaseObj;char* pDepartment;char* pCompany;int nSalary;//If there is any employee specific functions; add interface here.}Employee;Person* new_Employee(const char* const pFirstName, const char* const pLastName,const char* const pDepartment, const char* const pCompany, int nSalary);    //constructor
void delete_Employee(Person* const pPersonObj);    //destructorvoid Employee_DisplayInfo(Person* const pPersonObj);

employee.c

#include 
#include #include "employee.h"Person* new_Employee(const char* const pFirstName, const char* const pLastName,const char* const pDepartment, const char* const pCompany, int nSalary)
{ Employee* pEmpObj;//calling base class construtorPerson* pObj = new_person(pFirstName, pLastName);//allocating memorypEmpObj = malloc(sizeof(Employee));if (pEmpObj == NULL){ pObj->Delete(pObj);return NULL;}pObj->pDerivedObj = pEmpObj; //pointing to derived object//initialising derived class memberspEmpObj->pDepartment = malloc(sizeof(char)*(strlen(pDepartment)+1));if(pEmpObj->pDepartment == NULL){ return NULL;}strcpy(pEmpObj->pDepartment, pDepartment);pEmpObj->pCompany = malloc(sizeof(char)*(strlen(pCompany)+1));if(pEmpObj->pCompany== NULL){ return NULL;}strcpy(pEmpObj->pCompany, pCompany);pEmpObj->nSalary = nSalary;//Changing base class interface to access derived class functions//virtual destructor//person destructor pointing to destrutor of employeepObj->Delete = delete_Employee;pObj->Display = Employee_DisplayInfo;//pObj->WriteToFile = Employee_WriteToFile;printf("finish construct employee
");return pObj;
}void delete_Employee(Person* const pPersonObj)
{ if(!pPersonObj){ return;}Employee* pEmpObj;pEmpObj = pPersonObj->pDerivedObj;if(pEmpObj->pDepartment) { free(pEmpObj->pDepartment);pEmpObj->pDepartment = NULL;}if(pEmpObj->pCompany) { free(pEmpObj->pCompany);pEmpObj->pCompany = NULL;}pPersonObj->Delete(pPersonObj);
}void Employee_DisplayInfo(Person* const pPersonObj) { if(!pPersonObj) { printf("pPersonObj is null
");return;}Employee* pEmpObj;pEmpObj = pPersonObj->pDerivedObj;printf("pEmpObj's pDepartment is %s
",pEmpObj->pDepartment);printf("pEmpObj's pCompany is %s
",pEmpObj->pCompany);printf("pEmpObj's nSalary is %d
",pEmpObj->nSalary);
}

main.c

#include 
#include 
#include "person.h"
//#include "employee.h"int main(int argc, char *argv[]) { Person *obj;obj = new_person("pfirst_name","plast_name");obj -> Display(obj);obj -> WriteToFile(obj,"F:\test_write.txt");obj -> Delete(obj);Person *pobj;pobj = new_Employee("Gauri", "Jaiswal","HR", "TCS", 40000);pobj -> Display(pobj);pobj -> Delete(pobj);return 0;
}

更多相关:

  • 不透明指针(opaque pointer)可以用来在C中实现封装。 什么是不透明指针(opaque pointer) 从字面意思来看,“不透明”意味着看不到内部,因此“不透明指针”即看不到内部定义的指针。这样说有些抽象,我们来看个例子: #include typedef void *opque_data;...

  • 容器选择 取的元素很多,频繁的增删元素:linkedlist 涉及到增删,不频繁:linkedlist,arraylist 涉及到了增删,同时涉及到了查询:建议使用arraylist【一般情况增删不多,查询多】   Set:没有顺序,元素不可以重复 Set集合的功能和collection的功能是一致的。   Set两大子类 Hashs...

  • 创建新对象有两种不同的方法: 定义并创建对象的实例使用函数来定义对象,然后创建新的对象实例1.定义并创建对象的实例 var person=new Object(); person.firstname="John"; person.lastname="Doe"; person.age=50; person.eyecolor="blue...

  • 1、引用命名空间: using System.Runtime.Serialization; 2、json的序列化和反序列化的方法: publicclass JsonHelper {///

    /// 序列化/////////
  • mutable的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。   在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。   我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成cons...

  • 前言:很多人都把const int * 、int * const、int const* 的区别和联系搞混,我自己在学习C++的过程中,也经常性          弄不 清楚,今天特意总结一下,作为学习笔记记录下来。 一,const修饰符用于指针         将const用于指针有些很微妙的地方,有两种不同的方式将const关键...

  •   注意,前情提示: 本代码基于《Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)》 传送门Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)_你挚爱的强哥❤给你发来1条消息❤-CSDN博客   在/api/demo/文件夹下面创建exportAndDownl...

  • 项目结构 main.js(入口文件,开启9999端口监听,实现RESTful风格接口访问) const express = require("express"); const app = express(); const port = 9999;//设置端口号,如果端口号被占用需要自己修改,否则无法跑起来(建议不要用80和80...

  • ES6 你可能不知道的事 – 基础篇 转载 作者:淘宝前端团队(FED)- 化辰 链接:taobaofed.org/blog/2016/07/22/es6-basics/   序   ES6,或许应该叫 ES2015(2015 年 6 月正式发布),对于大多数前端同学都不陌生。   首先这篇文章不是工具书,不会去过多谈概念,而是...

  • char* Reverse(char* s) {//将q指向字符串最后一个字符char* q = s ;while( *q++ ) ;q -= 2 ; //分配空间,存储逆序后的字符串。char* p = newchar[sizeof(char) * (q - s + 2)] ; char* r = p ;// 逆序存储whil...

  • 二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {"abc", "def", "ghi"}; 这种模型为二级指针的第一种内存模型,在理解的时候应该这样理解:定义了一个指针数组(char *...

  • 今天在弄一下啊小小程序的时候。报错,出现了问题。先看代码 int main(int argc, char* argv[]) {char *filename = "interface_ipset_1_1.json";char* split1 = "_";char* split2 = ".";char splitfile1[4][...

  • wchar_t*,wchar_t,wchat_t数组,char,char*,char数组,std::string,std::wstring,CString....#include // 使用CString必须使用MFC,并且不可包含#define _AFXDLL#include us...

  • 问题的提出:设计一个用于管理朋友信息的程序。将朋友信息(年龄、姓名、电话)存放在MyFrd.dat中,从文件读出这些信息并显示,并能按姓名(要求可简化输入,如只输入姓氏便可查询)进行查询,将查询信息输出屏幕。 1 #include 2 #include 3 #include<...