其实关于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,今天先这样吧,接下来我们会说说更难一点的,因为接近尾声,所以更新得会有些“不积极”。
=======================================
回复D直接查看目录
原文始发于微信公众号(
C/C++的编程教室
):第八十讲 探索OI
|