第八十讲 探索OI

其实关于C++的内容不打算再说的了,所以这些天都没有推送,因为我在考虑接下来我们是该说COM呢还是MFC,因为在一开始的时候打算说MFC的,那时候我没有纠结过,后面我又想,MFC的局限性太大了,如果这样的话岂不是把大家捆绑在微软上面了吗?后来想了下,COM是不错的选择,虽然他是微软提出来的,但是他是一种与语言无关性的东西,我们可以用VB,抑或是C#,还是Java等等来开发COM组件,OK,废话不多说了,不管是MFC还是COM,我们现在都没时间来说,我们现在还是继续来看看C++吧,因为不管是MFC还是我们接下来要说的COM都和C++脱不了关系(因为我只会C++,所以就算说COM,我们也是用C++来开发)。

相信如果从头开始关注我们课堂的朋友也应该明白,其实我们C++的真正内容也没啥好说的,但现在想起来,上次留给大家一个问题,ok,我来重复一遍我们的问题:

—————————————-

在不使用iostream的时候我们怎么让下面的代码运行起来:

#include <stdlib.h>

int main(){

My_IO out;

MyInt a=5;

out<<a<<"

n"

;

//在控制台打印出5然后回车。

FILE* f(fopen("

Test.txt"

,"

w+"

));

My_IO fout(f);

fout<<a<<"

n"

;

//创建一个Test.txt文件,然后把5写进文本中;

return 0;

}

——————————————

这个问题看上去有些麻烦,其实只要把思路理清了也就那么回事,首先我们来看看C++到底是什么,最直接的是C++是C的超集,所以C++的很多东西都是C扩展而来的,他填了C的很多抗但同时也带来了新坑,不过这不是我们这里该讨论的问题,我们继续来看看这个问题。

MyInt是我们自定义的一个数据结构,从上面的内容,我们可以看得出,他就是封装了C++的int,这个MyInt是以前研究多线程的时候封装的一个class,大致内容如下:

—————————————–

#ifndef _MY_INT_H_

#define _MY_INT_H_

#include "

MyLock.h"

#include "

Myiostream.h"

using namespace My_Code;


class MyInt{

public:

MyInt();

MyInt(const MyInt&

);

MyInt(const int&

);

MyInt&

operator=(const MyInt&

);

MyInt&

operator=(const int&

);

MyInt operator–();

MyInt operator–(int);

const
int Get() const;

friend bool operator==(const MyInt&

_m1, const MyInt&

_m2);

friend bool operator<(const MyInt&

_m1, const MyInt&

_m2);

friend bool operator>(const MyInt&

_m1, const MyInt&

_m2);

friend Base_IO&

operator<<(Base_IO&

out, const MyInt&

m1);

private:

int _m;

CriticSection _safelock;

//这是我封装了的一个线程安全锁,反正以后会和大家说多线程的,所以现在知道这么回事就行了。

};

#endif

——————————————

大家注意到了,我们上面的#include "

Myiostream.h"

,重点就是这里了,可能大家会觉得奇怪,会想,我们是不是哪根筋出问题了,标准库里面有那么好用的iostream,干嘛还吃饱了没事来弄个io呢?那么我们换种想法,如果我们自己写了个类库,别人想要用我们的类库的时候,他们就不得不得连入iostream,这在对效率要求高的情况下是不可忍的,而且cout不是线程安全的,所以很多时候可能自己写个oi是不错的选择。

说了这些,那么我们还是没有说io到底是啥东西,好吧,当然我们这里不讨论i,我们来讨论o,o大家都知道那是叫输出,但是有些朋友没有想到另一层含义,o其实就是把东西写到某个地方,如果想到这一层想要写个io也就简单了,可以把他想象成下面这样:

—————————-

_f.send(void* _p);

—————————-

假设这个函数实现的目的是将_p的内容写到_f里,我们这里就假如是这样的,所以,按照oo思想,我们用一个抽象类来表示接口(以便以后我们需要派生其他类呢?),然后派生出我们需要的类,假如这个类暂时就是我们所需要的io了,那么我们将这个类封装我们想要去的地方(当然是我们要把数据写进去的目的地了),大家还记得FILE吗?如果忘记的话,回去看看C语言部分的文件的读写部分,那么我们的io可以如下:

——————————-

#ifndef _My_IOSTREAM_H_

#define _My_IOSTREAM_H_

#include <stdlib.h>

#include <stdio.h>

namespace My_Code{

class Base_IO{

public:

virtual ~Base_IO(){ }

virtual
void Send(const char*) = 0;

};


class My_IO :public Base_IO{

public:

My_IO(FILE* f=stdout) :_f(f){ } //_f有默认值,就是标准输入接口。


void Send(const char* str){

fputs(str, _f);

}

private:

FILE* _f;

};

}

#endif

————————————–

到这里,我们的程序可以完美运行了。

ok,今天先这样吧,接下来我们会说说更难一点的,因为接近尾声,所以更新得会有些“不积极”。

第八十讲 探索OI

=======================================

回复D直接查看目录

原文始发于微信公众号(

C/C++的编程教室

):第八十讲 探索OI

|

发表评论