原文地址:http://www.360doc.com/content/13/0218/10/8363527_266294787.shtml

良好的设计应该只暴露接口给用户,所有的实现细节对用户来说应该是隐藏的,也就是说用户只要给接口传递相应的参数就行了,不需要管内部是如何实现的,比如我们使用fopen,fseek,CreateWindow等函数会发现很好用,而不需要管fopen,fseek,CreateWindow函数内部代码是如何实现的,数据结构是如何组织的,也就是说绝对不能暴露任何的细节给用户,包括数据组织在内。

我现在用C和C++举一个例子,来说说C/C++分别是如何实现的,然后来看看哪种实现更好。

先来看C++用类实现的封装:

--------------------------- interface1.h ---------------------------

#ifndef INTERFACE1_H
#define INTERFACE1_H

class DATA
{
private:
    int _i;
    short _j;

public:
    DATA();
    ~DATA();

void set(int i, short j);
    void get(int* i, short* j);    
};

#endif

--------------------------- interface1.cpp ---------------------------

#include "interface1.h"

DATA::DATA()
{
    _i = _j = 0;
}

DATA::~DATA()
{
    _i = _j = 0;
}

void DATA::set(int i, short j)
{
    _i = i;
    _j = j;
}

void DATA::get(int* i, short* j)
{
    *i = _i;
    *j = _j;
}

--------------------------- test.cpp ---------------------------

#include <stdio.h>
#include "interface1.h"

int main()
{
    DATA data;
    int i;
    short j;

data.set(2, 3);
    data.get(&i, &j);
            
    printf("i = %d, j = %d\n", i, j);

return 0;
}
 

再来看 C 如何巧妙的封装以及隐藏实现细节:

---------------------------  interface.h  ---------------------------

#ifndef INTERFACE_H
#define INTERFACE_H

void* data_create();
void data_set(void* dummy, int i, short j);
void data_get(void* dummy, int* i, short * j);
void data_destroy(void* dummy);

#endif

---------------------------  interface.c  ---------------------------

#include <stdlib.h>

struct DATA
{
    int i;
    short j;
};

void* data_create()
{
    return malloc(sizeof(struct DATA));
}

void data_set(void* dummy, int i, short j)
{
    struct DATA* data = dummy;

data->i = i;
    data->j = j;
}

void data_get(void* dummy, int* i, short * j)
{
    struct DATA* data = dummy;

*i = data->i;
    *j = data->j;
}

void data_destroy(void* dummy)
{   
    free(dummy);
}

---------------------------  test.c  ---------------------------

#include <stdio.h>
#include "interface.h"

int main()
{
    int i;
    short j;

void* data = data_create();

data_set(data, 2, 3);

data_get(data, &i, &j);    
    printf("i = %d, j = %d\n", i, j);

data_destroy(data);

return 0;
}
 

可以看的出来,C的实现只暴露了接口给用户,内部的实现细节都隐藏了起来,可是C++用类实现反而在头文件暴露了实现细节。

当然用C++也可以做到只暴露接口给用户,不过实现起来会比较复杂,而且需要消耗更多的内存(使用了虚函数)。

-------------------------------------- parent.h --------------------------------------

#ifndef PARENT_H
#define PARENT_H

class PARENT
{
public:
    virtual void set(int i, short j) = 0; 
    virtual void get(int* i, short* j) = 0;
};

PARENT* get_child();

#endif

-------------------------------------- parent.cpp --------------------------------------

#include "parent.h"
#include "child.h"

PARENT* get_child()
{
    return new CHILD;
}

-------------------------------------- child.h --------------------------------------

#ifndef CHILD_H
#define CHILD_H

#include "parent.h"

class CHILD : public PARENT
{
private:
    int _i;
    short _j;

public:
    CHILD();
    ~CHILD();

void set(int i, short j);
    void get(int* i, short* j);    
};

#endif

-------------------------------------- child.cpp --------------------------------------

#include "child.h"

CHILD::CHILD()
{
    _i = _j = 0;
}

CHILD::~CHILD()
{
    _i = _j = 0;
}

void CHILD::set(int i, short j)
{
    _i = i;
    _j = j;
}

void CHILD::get(int* i, short* j)
{
    *i = _i;
    *j = _j;
}

-------------------------------------- test.cpp --------------------------------------

#include <stdio.h>
#include "parent.h"

int main()
{    
    int i;
    short j;

PARENT* parent = get_child();

parent->set(2, 3);
    parent->get(&i, &j);
            
    printf("i = %d, j = %d\n", i, j);

return 0;
}

c++接口实现与分离(转载)的更多相关文章

  1. C++中接口与实现分离的技术 ZZ

    最简单清晰的例子:http://www.cnblogs.com/maoye/archive/2010/03/19/1690183.html 接口与实现分离 为什么这样设计? 主要原因是保持接口的稳定, ...

  2. ZT 接口和实现分离

    什么叫接口和实现分离,如何实现 [问题点数:20分,结帖人heronism] http://bbs.csdn.net/topics/310212385 http://blog.csdn.net/sta ...

  3. JQuery1.11版本对prop和attr接口的含义分离导致问题分析

    问题背景 实验中, 在jquery1.7版本, attr("value")  和 val() 接口获取 input 控件的值, 都是一致的, 都是当前控件值. 但是 jquery1 ...

  4. Java _Map接口的使用(转载)

    转载自:http://blog.csdn.net/tomholmes7/article/details/2663379.转载请注明原作者地址 Map Map以按键/数值对的形式存储数据,和数组非常相似 ...

  5. 使用swagger实现web api在线接口文档(转载)

    一.前言 通常我们的项目会包含许多对外的接口,这些接口都需要文档化,标准的接口描述文档需要描述接口的地址.参数.返回值.备注等等:像我们以前的做法是写在word/excel,通常是按模块划分,例如一个 ...

  6. API接口测试用例编写规则(转载)

    API接口测试用例编写规则 (1)必需参数覆盖.对于接口的参数,接口文档一般都会说明哪些儿是必需的,哪儿是非必需的.对于必需的参数,一定要测试传参数和不传参数接口是否报错? (2)必需的参数各种情况覆 ...

  7. Hessian 接口使用示例总结(转载)

    一.使用hessian接口准备 首先,hessian接口的使用,必须要准备hessian接口的jar包,本文使用的jar包如下:hessian-4.0.7.jar; Hessian接口的使用一般是在两 ...

  8. yii 主从数据库分离-转载http://www.yiichina.com/doc/guide/2.0/db-dao

    数据库复制和读写分离 很多数据库支持数据库复制 database replication来提高可用性和响应速度. 在数据库复制中,数据总是从主服务器 到 从服务器. 所有的插入和更新等写操作在主服务器 ...

  9. java抽象类和接口的区别(转载)

    1.Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这大概就是Java抽象类唯一的优点吧,但这个优点非常有用. 如果向一个抽象类里加入 ...

随机推荐

  1. Centos6.4 aria2 webui-aria2

    wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm rpm -ivh ...

  2. .net操作数据库,史上最牛逼的方法,你见过这种方法吗

    免费分享给大家.下载地址在最下面. C# code   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...

  3. Mysql常见四种索引的使用

    提到MySQL优化,索引优化是必不可少的.其中一种优化方式 --索引优化,添加合适的索引能够让项目的并发能力和抗压能力得到明显的提升. 我们知道项目性能的瓶颈主要是在"查(select)&q ...

  4. WebViewJavascriptBridge详细使用(转载)

    WebViewJavascriptBridge是支持到iOS6之前的版本的,用于支持native的iOS与javascript交互.如果需要支持到iOS6之前的app,使用它是很不错的.本篇讲讲Web ...

  5. backup2

    /// <summary> /// 先在窗体上添加LicenceControl控件 /// Enable 3D analysis /// </summary> public v ...

  6. IE11错误:Exception in window.onload: An error has occuredJSPlugin.3005 解决方案

    问题:新安装的IE11无法使用F12开发者工具,DOC资源管理器提示错误“Exception in window.onload: An error has occuredJSPlugin.3005”. ...

  7. MySQL学习(一)

    mysql left join,right join,inner join用法分析 left join:是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的. 换句 ...

  8. Dalvik系列02 - 指令格式

    简介 该文档描述了Dalvik 可执行文件和Dalvik 字节码的指令格式. 按照位的描述 格式描述表(见下文)的第一列表示个格式的位结构,它由一个或者多个由空格分开的“指令单元”构成,每个指令单元的 ...

  9. 答:SQLServer DBA 三十问之二:系统DB有哪些,都有什么作用,需不需要做备份,为什么;损坏了如何做还原(主要是master库)

    2. 系统DB有哪些,都有什么作用,需不需要做备份,为什么:损坏了如何做还原(主要是master库): master:它包含一个系统表集合,是整个实例的中央存储库,维护登录账户,其他数据库,文件分布, ...

  10. 初学python之安装Jupyter notebook

    一开始安装python的时候,安装的是最新版的python3.6的最新版.而且怕出问题,选择的都是默认安装路径.以为这样总不会出什么问题.一开始确实这样,安装modgodb等一切顺利.然而在安装jup ...