??xml version="1.0" encoding="utf-8" standalone="yes"?>人人狠狠综合88综合久久,亚洲午夜精品久久久久久浪潮,亚洲另类欧美综合久久图片区http://www.shnenglu.com/mumutou/archive/2007/01/21/17856.html木木?/dc:creator>木木?/author>Sun, 21 Jan 2007 04:36:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/21/17856.htmlhttp://www.shnenglu.com/mumutou/comments/17856.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/21/17856.html#Feedback0http://www.shnenglu.com/mumutou/comments/commentRss/17856.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17856.html阅读全文

]]>
UML随笔 ?Rose对VC的正?反向工程http://www.shnenglu.com/mumutou/archive/2007/01/21/17855.html木木?/dc:creator>木木?/author>Sun, 21 Jan 2007 04:35:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/21/17855.htmlhttp://www.shnenglu.com/mumutou/comments/17855.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/21/17855.html#Feedback1http://www.shnenglu.com/mumutou/comments/commentRss/17855.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17855.html ?/span> [IBM 软gpd ].IBM.Rational.Rose.Enterprise.v7.0-TFTISO 建立镜像后安?/span>

打开 Rose 软g

׃本hl常使用 VC6.0 开发Y?/span>

首先来谈?/font>

Rose 关于 VC6.0 的正向和逆向工程?/span>

Rose d?/span> 5 U类型图

̔ (tng) (tng) (tng) (tng) (tng) (tng) (tng) Use Case View

̔ (tng) (tng) (tng) (tng) (tng) (tng) (tng) Logical View

̔ (tng) (tng) (tng) (tng) (tng) (tng) (tng) Component View

̔ (tng) (tng) (tng) (tng) (tng) (tng) (tng) Deployment View

̔ (tng) (tng) (tng) (tng) (tng) (tng) (tng) Model Properties 其实q不能说是一U图

 (tng)

现在我们先来谈谈 Logical View 是?rn)态图Q?/span>

l常我们使用它来做一些静(rn)态类库?/font>

好了(jin)Q先来看看反向工E吧

[tools]->[Visual C++]->[Update Model From Code]

出现 Model Update Tool-Select Components and Classes

如果?/span> VC++ 下面没有的话,点击 Add Component, d一个要施行逆向工程?/span> VC 工程

点击工程下面所有的c,点击 Next 可以了(jin)?/span>

 (tng)

 (tng)

我们再来看看正向工程

[tools]->[Visual C++]->[Update Code]

同样安装以上操作可以了(jin)

 (tng)

如果我们d一个类的话Q那么就必须要?/font>

[Tools]->[Visual C++]->[Component Assignment Tool] 来把d的类包含到实行正向工E的 VC 工程里面?/span>

 (tng)

 (tng)

 (tng)

 (tng)

 (tng)



]]>
UML随笔 ?c?关系http://www.shnenglu.com/mumutou/archive/2007/01/19/17776.html木木?/dc:creator>木木?/author>Fri, 19 Jan 2007 04:04:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/19/17776.htmlhttp://www.shnenglu.com/mumutou/comments/17776.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/19/17776.html#Feedback0http://www.shnenglu.com/mumutou/comments/commentRss/17776.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17776.htmlcdpLd分ؓ(f)
1.l承关系[一般化关系]
class A{};
class B:public A
{};
A和B是承关p?br />2.兌关系
class A{};
class B
{
 (tng) (tng) (tng)void (tng) (tng) (tng)Function1(A *a);
}
A和B是关联关p?br />3.聚合关系
class A{};
class B
{
 (tng) (tng) (tng)A *a;
};
A和B是聚合关p?br />比如XX?jng)这个?br />class XX?br />{
 (tng) (tng) (tng)力_局 (tng) (tng) (tng)*力_局1;
 (tng) (tng) (tng)供电(sh)局 *供电(sh)局1;
 (tng) (tng) (tng)_食局 *_食局1;
};
4.l合关系
class A{};
class B
{
 (tng) (tng) (tng)A a;
};
A和B是组合关p?br />
l合关系和聚合关pLhQ其强度要高?sh)点;


]]>C++随笔 ?C++风格的类型{换的用法 (转蝲)http://www.shnenglu.com/mumutou/archive/2007/01/16/17682.html木木?/dc:creator>木木?/author>Tue, 16 Jan 2007 05:24:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/16/17682.htmlhttp://www.shnenglu.com/mumutou/comments/17682.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/16/17682.html#Feedback0http://www.shnenglu.com/mumutou/comments/commentRss/17682.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17682.html C++风格的类型{换的用法

q是More Effecitve C++里的W二条对cd转换讲的很好Q也很基好懂?br />Item M2Q尽量用C++风格的类型{?br />仔细x(chng)C卑贱的类型{换功能(castQ,其在E序设计中的Cpgoto语句一样o(h)人鄙视。但是它q(sh)是无法o(h)人忍受,因ؓ(f)当在某些紧要的关_(d)cd转换q是必需的,q时它是一个必需品?br />不过C风格的类型{换ƈ不代表所有的cd转换功能?br />一来它们过于粗鲁,能允怽在Q何类型之间进行{换。不q如果要q行更精的cd转换Q这?x)是一个优炏V在q些cd转换中存在着巨大的不同,例如把一个指?const对象的指针(pointer-to-const-objectQ{换成指向非const对象的指针(pointer-to-non-const -objectQ?即一个仅仅去除const的类型{?Q把一个指向基cȝ指针转换成指向子cȝ指针Q即完全改变对象cdQ。传l的C风格的类型{换不对上qCU{换进行区分。(q一点也不o(h)人惊Ӟ因ؓ(f)C风格的类型{换是为C语言设计的,而不是ؓ(f)C++语言设计的)(j)?br />二来C风格的类型{换在E序语句中难以识别。在语法上,cd转换由圆括号和标识符l成Q而这些可以用在CQ+中的M地方。这使得回答象这样一个最基本的有关类型{换的问题变得很困难:(x)“在q个E序中是否用了(jin)cd转换Q”。这是因Zh工阅d可能忽略?jin)类型{换的语句Q而利用象grep的工L(fng)序也不能从语句构成上区分出它们来?br />C++通过引进四个新的cd转换操作W克服了(jin)C风格cd转换的缺点,q四个操作符? static_cast, const_cast, dynamic_cast, 和reinterpret_cast。在大多数情况下Q对于这些操作符你只需要知道原来你?fn)惯于这样写Q?br />(type) expression
而现在你d该这样写Q?br />static_cast<type>(expression)
例如Q假设你x(chng)一个int转换成doubleQ以便让包含intcd变量的表辑ּ产生出QҎ(gu)值的l果。如果用C风格的类型{换,你能q样写:(x)
int firstNumber, secondNumber;
...
double result = ((double)firstNumber)/secondNumberQ?br />如果用上q新的类型{换方法,你应该这样写Q?br />double result = static_cast<double>(firstNumber)/secondNumber;
q样的类型{换不论是对h工还是对E序都很Ҏ(gu)识别?br />static_cast 在功能上基本上与C风格的类型{换一样强大,含义也一栗它也有功能上限制。例如,你不能用static_cast象用C风格的类型{换一h struct转换成intcd或者把doublecd转换成指针类型,另外Qstatic_cast不能从表辑ּ中去除const属性,因ؓ(f)另一个新的类型{换操作符const_cast有这L(fng)功能?br />其它新的C++cd转换操作W被用在需要更多限制的地方。const_cast用于cd转换掉表辑ּ的const或volatileness属性。通过使用const_castQ你向h们和~译器强调你通过cd转换惛_的只是改变(sh)些东西的 constness或者volatileness属性。这个含义被~译器所U束。如果你试图使用const_cast来完成修改constness 或者volatileness属性之外的事情Q你的类型{换将被拒l。下面是一些例子:(x)
class Widget { ... };
class SpecialWidget: public Widget { ... };
void update(SpecialWidget *psw);
SpecialWidget sw; // sw 是一个非const 对象?br />const SpecialWidget& csw = sw; // csw 是sw的一个引?br />// 它是一个const 对象
update(&csw); // 错误!不能传递一个const SpecialWidget* 变量
// l一个处理SpecialWidget*cd变量的函?br />update(const_cast<SpecialWidget*>(&csw));
// 正确Qcsw的const被显C地转换掉(
// csw和sw两个变量值在update
//函数中能被更斎ͼ(j)
update((SpecialWidget*)&csw);
// 同上Q但用了(jin)一个更难识?br />//的C风格的类型{?br />Widget *pw = new SpecialWidget;
update(pw); // 错误Qpw的类型是Widget*Q但?br />// update函数处理的是SpecialWidget*cd
update(const_cast<SpecialWidget*>(pw));
// 错误Qconst_cast仅能被用在媄(jing)?br />// constness or volatileness的地方上?
// 不能用在向承子c进行类型{换?br />到目前ؓ(f)止,const_cast最普通的用途就是{换掉对象的const属性?br />W二U特D的cd转换W是dynamic_castQ它被用于安全地沿着cȝl承关系向下q行cd转换。这是_(d)你能用dynamic_cast把指向基cȝ指针或引用{换成指向其派生类或其兄弟cȝ指针或引用,而且你能知道转换是否成功。失败的转换返回空指针Q当Ҏ(gu)针进行类型{换时Q或者抛出异常(当对引用q行cd转换Ӟ(j)Q?br />Widget *pw;
...
update(dynamic_cast<SpecialWidget*>(pw));
// 正确Q传递给update函数一个指?br />// 是指向变量类型ؓ(f)SpecialWidget的pw的指?br />// 如果pw实指向一个对?
// 否则传递过ȝɽI指针?br />void updateViaRef(SpecialWidget& rsw);
updateViaRef(dynamic_cast<SpecialWidget&>(*pw));
//正确。传递给updateViaRef函数
// SpecialWidget pw 指针Q如果pw
// 实指向?jin)某个对?br />// 否则抛出异?br />dynamic_casts在帮助你览l承层次上是有限制的。它不能被用于缺乏虚函数的类型上Q参见条ƾM24Q,也不能用它来转换掉constnessQ?br />int firstNumber, secondNumber;
...
double result = dynamic_cast<double>(firstNumber)/secondNumber;
// 错误Q没有承关p?br />const SpecialWidget sw;
...
update(dynamic_cast<SpecialWidget*>(&sw));
// 错误! dynamic_cast不能转换
// 掉const?br />如你惛_没有l承关系的类型中q行转换Q你可能惛_static_cast。如果是Z(jin)去除constQ你d用const_cast?br />q四个类型{换符中的最后一个是reinterpret_cast。用这个操作符的类型{换,其的转换l果几乎都是执行期定义(implementation-definedQ。因此,使用reinterpret_casts的代码很隄植?br />reinterpret_casts的最普通的用途就是在函数指针cd之间q行转换。例如,假设你有一个函数指针数l:(x)
typedef void (*FuncPtr)(); // FuncPtr is 一个指向函?br />// 的指针,该函数没有参?br />// q回值类型ؓ(f)void
FuncPtr funcPtrArray[10]; // funcPtrArray 是一个能容纳
// 10个FuncPtrs指针的数l?br />让我们假设你希望Q因为某些莫名其妙的原因Q把一个指向下面函数的指针存入funcPtrArray数组Q?br />int doSomething();
你不能不l过cd转换而直接去做,因ؓ(f)doSomething函数对于funcPtrArray数组来说有一个错误的cd。在FuncPtrArray数组里的函数q回值是voidcdQ而doSomething函数q回值是intcd?br />funcPtrArray[0] = &doSomething; // 错误Q类型不匚w
reinterpret_cast可以让你qɾ~译器以你的Ҏ(gu)ȝ待它们:(x)
funcPtrArray[0] = // this compiles
reinterpret_cast<FuncPtr>(&doSomething);
转换函数指针的代码是不可UL的(C++不保证所有的函数指针都被用一L(fng)Ҏ(gu)表示Q,在一些情况下q样的{换会(x)产生不正的l果Q参见条ƾM31Q,所以你应该避免转换函数指针cdQ除非你处于着背水一战和刀架喉的危急时刅R一把锋利的刀。一把非帔R利的刀?br />如果你用的~译器缺乏对新的cd转换方式的支持,你可以用传统的类型{换方法代替static_cast, const_cast, 以及(qing)reinterpret_cast。也可以用下面的宏替换来模拟新的cd转换语法Q?br />#define static_cast(TYPE,EXPR) ((TYPE)(EXPR))
#define const_cast(TYPE,EXPR) ((TYPE)(EXPR))
#define reinterpret_cast(TYPE,EXPR) ((TYPE)(EXPR))
你可以象q样使用使用Q?br />double result = static_cast(double, firstNumber)/secondNumber;
update(const_cast(SpecialWidget*, &sw));
funcPtrArray[0] = reinterpret_cast(FuncPtr, &doSomething);
q些模拟不会(x)象真实的操作W一样安全,但是当你的编译器可以支持新的的类型{换时Q它们可以简化你把代码升U的q程?br />没有一个容易的Ҏ(gu)来模拟dynamic_cast的操作,但是很多函数库提供了(jin)函数Q安全地在派生类与基cM间进行类型{换。如果你没有q些函数而你有必进行这L(fng)cd转换Q你也可以回到C风格的类型{换方法上Q但是这L(fng)话你不能获知类型{换是否失败。当?dng)你也可以定义一个宏来模?dynamic_cast的功能,p模拟其它的类型{换一P(x)
#define dynamic_cast(TYPE,EXPR) (TYPE)(EXPR)
误住,q个模拟q不能完全实现dynamic_cast的功能,它没有办法知道{换是否失败?br />我知道,是的Q我知道Q新的类型{换操作符不是很美观而且用键盘键入也很麻?ch)。如果你发现它们看上d在o(h)厌,C风格的类型{换还可以l箋使用q且合法。然而,正是因ؓ(f)新的cd转换W缺乏美感才能它I补了(jin)在含义精性和可L认性上的缺炏Vƈ且,使用新类型{换符的程序更Ҏ(gu)被解析(不论是对人工q是对于工具E序Q,它们允许~译器检出原来不能发现的错误。这些都是放弃C风格cd转换Ҏ(gu)的强有力的理由。还有第三个理由Q也许让cd转换W不观和键入麻?ch)是一件好事?



]]>
C++随笔 ?explicit 关键?转蝲)http://www.shnenglu.com/mumutou/archive/2007/01/16/17681.html木木?/dc:creator>木木?/author>Tue, 16 Jan 2007 05:21:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/16/17681.htmlhttp://www.shnenglu.com/mumutou/comments/17681.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/16/17681.html#Feedback0http://www.shnenglu.com/mumutou/comments/commentRss/17681.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17681.htmlexplicit关键字用于取消构造函数的隐式转换Q对有多个参数的构造函C用explicit是个语法错误?br />


In C++ it is possible to declare constructors for a class, taking a single parameter, and use those constructors for doing type conversion. For example:

				
class  (tng)A (tng){
public
:
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) A(
int
);
};

void
 (tng)f(A) (tng){}
void
 (tng)g()
{
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) A (tng)a1 (tng)
=  (tng) 37
;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) A (tng)a2 (tng)
=  (tng)A( 47
);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) A (tng)a3(
57
);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) a1 (tng)
=  (tng) 67
;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) f(
77
);
}

A declaration like:
 (tng)A a1 = 37;
says to call the A(int) constructor to create an A object from the integer value. Such a constructor is called a "converting constructor".

However, this type of implicit conversion can be confusing, and there is a way of disabling it, using a new keyword "explicit" in the constructor declaration:

				
class  (tng)A (tng){
public
:
 (tng) (tng) (tng) (tng) (tng) (tng) (tng)
explicit  (tng)A( int
);
};

void
 (tng)f(A) (tng){}
void
 (tng)g()
{
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) A (tng)a1 (tng)
=  (tng) 37 ; (tng) (tng) (tng) (tng) (tng) (tng) //  (tng)illegal

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) A (tng)a2 (tng) =  (tng)A( 47 ); (tng) (tng) (tng) //  (tng)OK
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) A (tng)a3( 57 ); (tng) (tng) (tng) (tng) (tng) (tng) (tng) //  (tng)OK
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) a1 (tng) =  (tng) 67 ; (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) //  (tng)illegal
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) f( 77 ); (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) //  (tng)illegal
}


Using the explicit keyword, a constructor is declared to be
"nonconverting", and explicit constructor syntax is required:

				
class  (tng)A (tng){
public
:
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
explicit  (tng)A( int
);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)};

void
 (tng)f(A) (tng){}

void
 (tng)g()
{
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)A (tng)a1 (tng)
=  (tng)A( 37
);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)A (tng)a2 (tng)
=  (tng)A( 47
);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)A (tng)a3(
57
);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)a1 (tng)
=  (tng)A( 67
);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)f(A(
77
));
}


Note that an expression such as:

				        A(47)

is closely related to function-style casts supported by C++. For example:

				        double d = 12.34;

int i = int(d);


木木?/a> 2007-01-16 13:21 发表评论
]]>C++随笔 ?文g操作(转蝲)http://www.shnenglu.com/mumutou/archive/2007/01/16/17680.html木木?/dc:creator>木木?/author>Tue, 16 Jan 2007 05:18:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/16/17680.htmlhttp://www.shnenglu.com/mumutou/comments/17680.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/16/17680.html#Feedback0http://www.shnenglu.com/mumutou/comments/commentRss/17680.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17680.html C++文g操作  (tng)原文地址Qhttp://www.layz.net/blog/user1/xuanxuan/archives/2006/67.html
 (tng)在C++中,有一个streamq个c,所有的I/O都以q个“流”类为基的,包括我们要认识的文gI/OQstreamq个cL两个重要的运符Q?

1、插入器(<<)
  向流输出数据。比如说pȝ有一个默认的标准输出?cout)Q一般情况下是指的昄器,所以,cout<<"Write Stdout"<<'\n';pC把字符?Write Stdout"和换行字W?'\n')输出到标准输出流?

2、析取器(>>)
  从流中输入数据。比如说pȝ有一个默认的标准输入?cin)Q一般情况下是指的键盘Q所以,cin>>x;pCZ标准输入中d一个指定类?卛_量x的类?的数据?

  在C++中,Ҏ(gu)件的操作是通过stream的子cfstream(file stream)来实现的Q所以,要用q种方式操作文gQ就必须加入头文件fstream.h。下面就把此cȝ文g操作q程一一道来?

一、打开文g
  在fstreamcMQ有一个成员函数open()Q就是用来打开文g的,其原型是Q?

void open(const char* filename,int mode,int access);

参数Q?

filenameQ  要打开的文件名
modeQ    要打开文g的方?
accessQ   打开文g的属?
打开文g的方式在cios(是所有流式I/Ocȝ基类)中定义,常用的值如下:(x)

ios::appQ   以追加的方式打开文g
ios::ateQ   文g打开后定位到文g,ios:app包含有此属?
ios::binaryQ? 以二q制方式打开文gQ缺省的方式是文本方式。两U方式的区别见前?
ios::inQ    文g以输入方式打开
ios::outQ   文g以输出方式打开
ios::nocreateQ?不徏立文Ӟ所以文件不存在时打开p| 
ios::noreplaceQ不覆盖文gQ所以打开文g时如果文件存在失?
ios::truncQ  如果文g存在Q把文g长度设ؓ(f)0
  可以用“或”把以上属性连接v来,如ios::out|ios::binary

  打开文g的属性取值是Q?

0Q普通文Ӟ打开讉K
1Q只L?
2Q隐含文?
4Q系l文?
  可以用“或”或者?”把以上属性连接v?Q如3?|2是以只d隐含属性打开文g?

  例如Q以二进制输入方式打开文gc:\config.sys

  fstream file1;
  file1.open("c:\\config.sys",ios::binary|ios::in,0);

  如果open函数只有文g名一个参敎ͼ则是以读/写普通文件打开Q即Q?

  file1.open("c:\\config.sys");<=>file1.open("c:\\config.sys",ios::in|ios::out,0);

  另外Qfstreamq有和open()一L(fng)构造函敎ͼ对于上例Q在定义的时侯就可以打开文g?jin)?x)

  fstream file1("c:\\config.sys");

  特别提出的是Qfstream有两个子c:(x)ifstream(input file stream)和ofstream(outpu file stream)Qifstream默认以输入方式打开文gQ而ofstream默认以输出方式打开文g?

  ifstream file2("c:\\pdos.def");//以输入方式打开文g
  ofstream file3("c:\\x.123");//以输出方式打开文g

  所以,在实际应用中Q根据需要的不同Q选择不同的类来定义:(x)如果想以输入方式打开Q就用ifstream来定义;如果想以输出方式打开Q就用ofstream来定义;如果想以输入/输出方式来打开Q就用fstream来定义?

二、关闭文?
  打开的文件用完成后一定要关闭Qfstream提供?jin)成员函数close()来完成此操作Q如Qfile1.close();把file1相连的文件关闭?

三、读写文?
  d文g分ؓ(f)文本文g和二q制文g的读取,对于文本文g的读取比较简单,用插入器和析取器可以了(jin)Q而对于二q制的读取就要复杂些Q下要就详细的介l这两种方式

  1、文本文件的d
  文本文g的读写很单:(x)用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开Qfile2以输出打开。示例如下:(x)

  file2<<"I Love You";//向文件写入字W串"I Love You"
  int i;
  file1>>i;//从文件输入一个整数倹{?

  q种方式q有一U简单的格式化能力,比如可以指定输出?6q制{等Q具体的格式有以下一?

操纵W?功能 输入/输出
dec 格式化ؓ(f)十进制数值数?输入和输?
endl 输出一个换行符q刷新此?输出
ends 输出一个空字符 输出
hex 格式化ؓ(f)十六q制数值数?输入和输?
oct 格式化ؓ(f)八进制数值数?输入和输?
setpxecision(int p) 讄点数的_ֺ位数 输出

  比如要把123当作十六q制输出Qfile1<<<123;要把3.1415926?位精度输出:(x)FILE1<<<3.1415926?

  2、二q制文g的读?
①put()
  put()函数向流写入一个字W,其原型是ofstream &put(char ch)Q用也比较单,如file1.put('c');是向流写一个字W?c'?

②get()
  get()函数比较灉|Q有3U常用的重蝲形式Q?

  一U就是和put()对应的Ş式:(x)ifstream &get(char &ch);功能是从中d一个字W,l果保存在引用ch中,如果到文件尾Q返回空字符。如file2.get(x);表示从文件中d一个字W,q把d的字W保存在x中?

  另一U重载Ş式的原型是:(x) int get();q种形式是从中q回一个字W,如果到达文g,q回EOFQ如x=file2.get();和上例功能是一L(fng)?

  q有一UŞ式的原型是:(x)ifstream &get(char *buf,int num,char delim='\n')Q这UŞ式把字符d?buf 指向的数l,直到d?num 个字W或遇到?jin)?delim 指定的字W,如果没?delim q个参数Q将使用~省值换行符'\n'。例如:(x)

  file2.get(str1,127,'A');//从文件中d字符到字W串str1Q当遇到字符'A'或读取了(jin)127个字W时l止?

③读写数据块
  要读写二q制数据块,使用成员函数read()和write()成员函数Q它们原型如下:(x)

    read(unsigned char *buf,int num);
    write(const unsigned char *buf,int num);

  read()从文件中d num 个字W到 buf 指向的缓存(sh)Q如果在q未d num 个字W时到?jin)文件尾Q可以用成员函数 int gcount();来取得实际读取的字符敎ͼ?write() 从buf 指向的缓存写 num 个字W到文g中,值得注意的是~存的类型是 unsigned char *Q有时可能需要类型{换?

例:(x)

    unsigned char str1[]="I Love You";
    int n[5];
    ifstream in("xxx.xxx");
    ofstream out("yyy.yyy");
    out.write(str1,strlen(str1));//把字W串str1全部写到yyy.yyy?
    in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数Q注意类型{?
    in.close();out.close();

四、检EOF
  成员函数eof()用来(g)是否到达文件尾Q如果到达文件尾q回?|否则q回0。原型是int eof();

例:(x)  if(in.eof())ShowMessage("已经到达文g!");

五、文件定?
  和C的文件操作方式不同的是,C++ I/Opȝ理两个与一个文件相联系的指针。一个是L针,它说明输入操作在文g中的位置Q另一个是写指针,它下ơ写操作的位|。每ơ执行输入或输出Ӟ相应的指针自动变化。所以,C++的文件定位分位置和写位置的定位,对应的成员函数是 seekg()?seekp()Qseekg()是设|读位置Qseekp是设|写位置。它们最通用的Ş式如下:(x)

    istream &seekg(streamoff offset,seek_dir origin);
    ostream &seekp(streamoff offset,seek_dir origin);

  streamoff定义?iostream.h 中,定义有偏U量 offset 所能取得的最大|seek_dir 表示Ud的基准位|,是一个有以下值的枚DQ?

ios::begQ  文g开?
ios::curQ  文g当前位置
ios::endQ  文gl尾
  q两个函C般用于二q制文gQ因为文本文件会(x)因ؓ(f)pȝ对字W的解释而可能与预想的g同?

例:(x)

     file1.seekg(1234,ios::cur);//把文件的L针从当前位置向后U?234个字?
     file2.seekp(1234,ios::beg);//把文件的写指针从文g开头向后移1234个字?/setpxecision(5)>


]]>
C++随笔 ?函数模板(Function Template)1 (原创)http://www.shnenglu.com/mumutou/archive/2007/01/10/17497.html木木?/dc:creator>木木?/author>Wed, 10 Jan 2007 06:36:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/10/17497.htmlhttp://www.shnenglu.com/mumutou/comments/17497.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/10/17497.html#Feedback0http://www.shnenglu.com/mumutou/comments/commentRss/17497.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17497.html1.Function Template可以针对不同的Template arguments完成一个系列的函数
例如
template<typename T>
inline T const & max(T const &a,T const &b)
{
 (tng) (tng) (tng)return (tng) (tng) (tng)a>b?a:b;
}
2.Function template可以从传递过来的arguments的类型来具体?br />int a = ::max(10,20);
那么F(tun)unction template 具体化?br />inline int const& max(int const &a,int const & b)
3.你可以具体指出它的参数类?br />int a = ::max<int>(10,20);
4.Function template可以被重载overloaded
inline T const& max(T const &a,T const &b,T const &c)
{
 (tng) (tng) (tng)return ::max(::max(a,b),c);
}
当然C一点,重蝲的相似点小好

]]>
C++随笔 ?关于C++中的指针问题 http://www.shnenglu.com/mumutou/archive/2007/01/09/17458.html木木?/dc:creator>木木?/author>Tue, 09 Jan 2007 05:48:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/09/17458.htmlhttp://www.shnenglu.com/mumutou/comments/17458.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/09/17458.html#Feedback1http://www.shnenglu.com/mumutou/comments/commentRss/17458.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17458.html 原文出处
http://community.csdn.net/Expert/topic/5279/5279199.xml?temp=.2457392
在文章中大家在讨Z个问?
如果没有存储上没有区别的?L(fng)下例Q?br />float a=3.45;
int * p1=&a;
float * p2=&a;
cout<<"p1"<<"=>"<<*p1<<endl;
cout<<"p2"<<"=>"<<*p2<<endl;

l果是:(x)
p1=>1107951616
p2=>3.45

书上的解释是Qp1管与p2的地址相同Q但它是整型指针Q它L讉K该地址中的整型数?br />首先?2位CPU上面,指针都是4位的,例如0xXX XX XX XX
那么既然指针是一L(fng),那么Z么指针类型不同的?d来的数据变?sh)(jin)样?
q是~译器的问题,例如我有个例?br />
char *p = 'c';
int *p1 = 10;
?2位机器上?br />q里面p1是指?字节的int变量,而p是指?字节的char 变量
q样~译器在用p1变量的时??x)?x XX XX XX XX后面?个字?br />而p变量,只会(x)?x XX XX XX XX后面?个字?br />
因ؓ(f)本h现在在网吧里面[不知道大家有没有在网吧里面碰到装有c++~译器的计算机]
晚上我给大家一个例?可以从其内存?sh)面看的很清?/font>



]]>
C++随笔 ?泛型~程与设计新思维(转蝲)http://www.shnenglu.com/mumutou/archive/2007/01/04/17238.html木木?/dc:creator>木木?/author>Thu, 04 Jan 2007 07:07:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/04/17238.htmlhttp://www.shnenglu.com/mumutou/comments/17238.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/04/17238.html#Feedback0http://www.shnenglu.com/mumutou/comments/commentRss/17238.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17238.html (tng) (tng)作者:(x)徐景?br />
 (tng) (tng) (tng)永远CQ编写代码的宗旨在于单明?jin),不要使用语言中的冷僻Ҏ(gu),耍小聪明Q重要的是编写你理解的代码,理解你编写的代码Q这样你可能?x)做的更好?
--- Herb Sutter

 (tng) (tng) (tng) 1998q_(d)国际C++标准正式通过Q标准化对C++最重要的A(ch)献是Q对"强大的抽象概?l于更有力的支持Q以降低软g的复杂度QC++提供?jin)二U功能强大的抽象Ҏ(gu)Q面向对象编E与泛型~程。面向对象编E大家一定很熟?zhn)了(jin),q里׃再哆嗦了(jin)。提到泛型编E?Generic Programming)Q有的h可能q(sh)太熟(zhn),但是提到STLQ你׃定会(x)有所耳闻?jin)。STL(Standard Template LibraryQ标准模板库) 其实是泛型~程的实现品QSTL是由Alexander Stepanov(STL之父)、David R Musser和Meng Lee三位大师共同发展Q于1994q被U_C++标准E序库。STL虽然加入C++标准库的旉相对较晚Q但它却是C++标准E序库中最具革命性的部分Q同时也是C++标准E序库中最重要的组成部分。由于新的C++标准库中几乎每一样东襉K是由模板(Template)构成的,当然QSTL也不?x)例外。所以,在这里有必要先概要说明一下模板的有关概念?

模板概念
 (tng) (tng) (tng) 通过使用模板可以使程序具有更好的代码重用性。记住,模板是对源代码进行重用,而不是通过l承和组合重用对象代码,当用户用模板时Q参数由~译器来替换。模板由cL板和函数模板二部分组成,以所处理的数据类型的说明作ؓ(f)参数的类叫cL板,而以所处理的数据类型的说明作ؓ(f)参数的函数叫做函数模ѝ模板参数可以由cd参数或非cd参数l成Q类型参数可用class和typename关键字来指明Q二者的意义相同Q都表示后面的参数名代表一个潜在的内置或用户定义的cdQ非cd参数׃个普通参数声明构成。下面是cL板和函数模板的简单用法:(x) template<class T1, int Size> class Queue // cL板,其中T1为类型参敎ͼSize为非cd参数 { public: explicit Queue():size_(Size){}; // 昑ּ构造,避免隐式转换 …?template<class T2> void assign(T2 first,T2 last); // 内嵌函数模板 private: T* temp_; int size_; } // cL板中内嵌函数模板Compare的外围实?如在Queuecd实现) template<class T1,int Size> template<class T2> void Queue<T1,Size>::assign (T2 first,T2 last) {}; // 模板的用方?int ia[4] = {0,1,2,3}; Queue<int, sizeof(ia)/sizeof(int)> qi; qi.assign(ai,ai+4); 泛型~程
 (tng) (tng) (tng) 泛型~程和面向对象编E不同,它ƈ不要求你通过额外的间接层来调用函敎ͼ它让你编写完全一般化q可重复使用的算法,其效率与针对某特定数据类型而设计的法相同。泛型编E的代表作品STL是一U高效、泛型、可交互操作的Y件组件。所谓泛?Genericity)Q是指具有在多种数据cd上皆可操作的含意Q与模板有些怼。STL巨大Q而且可以扩充Q它包含很多计算机基本算法和数据l构Q而且算法与数据l构完全分离Q其中算法是泛型的,不与M特定数据l构或对象类型系在一赗STL以P代器(Iterators)和容?Containers)为基Q是一U泛型算?Generic Algorithms)库,容器的存在ɘq些法有东西可以操作。STL包含各种泛型法(algorithms)、泛型指?iterators)、泛型容?containers)以及(qing)函数对象(function objects)。STLq只是一些有用组件的集合Q它是描qY件组件抽象需求条件的一个正规而有条理的架构?
 (tng) (tng) (tng) q代?Iterators)是STL的核?j),它们是泛型指针,是一U指向其他对?objects)的对象,q代器能够遍历由对象所形成的区?range)。P代器让我们得以将容器(containers)与作用其上的法(algorithms)分离Q大多数的算法自wƈ不直接操作于容器上,而是操作于P代器所形成的区间中。P代器一般分ZU:(x)Input Iterator、Output Iterator、Forward Iterator、Bidirections Iterator和Random Access Iterator。Input Iteratorp只从输入区间中读取数据一Ph只读性,属于单向UdQ如STL中的istream_iterator。Output Iterator刚好相反Q只写出数据到输出区间中Q具有只写性,属于单向UdQ如STL中的ostream_iterator。Forward Iterator也属于单向移动,但不同之处是它同时具有数据读、写性。Bidirections Iterator如名U暗C,支持双向UdQ不但可以篏?++)取得下一个元素,而且可以递减(--)取前一个元素,支持诅R写性。Random Access Iterator功能最强,除了(jin)以上各P代器的功能外Q还支持随机元素讉K(p+=n)Q下?p[n])、相?p1-p2)?qing)前后次序关p?p1<p2){。Input Iterator和Output Iterator属于同等最q二种q代器,Forward Iterator是前二者功能的强化(refinement)QBidirections Iterator又是Forward Iteratorq代器的强化Q最后Random Access Iterator又是Bidirections Iteratorq代器的强化。如下简单示例展CInput Iterator、Forward Iterator、Bidirections Iterator和Radom Access Iteratorq代器的功能Q其中input_iterator_tag{带tag字符串ؓ(f)各不同P代器的专属标识)(j)Q?
1、InputIterator template<class InputIterator, class Distance> void advance(InputIterator& i, Distance n, input_iterator_tag) { for(; n>0; --n,++i){} // InputIteratorh++?} 2、ForwardIterator template<class ForwardIterator, class Distance> void advance(ForwardIterator& i, Distance n,forward_iterator_tag) { advance(i, n, input_iterator_tag()); } 3、BidirectionalIterator template<class BidirectionalIterator, class Distance> void advance(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag) { if(n>=0) // h++?-?for(; n>0; --n,++i){} else for(; n>0; ++n,--i){} } 4、RandomAccessIterator template<class RandomAccessIterator, class Distance> void advance(RandomAccessIterator& i, Distance n, random_access_iterator_tag) { i += n; // h++?-?={?}  (tng) (tng) (tng) 函数对象(Function object)也称仿函?Functor)Q是一U能以一般函数调用语法来调用的对象,函数指针(Function pointer)是一U函数对象,所有具有operator()操作W重载的成员函数也是函数对象。函数对象一般分为无参函?Generator)Q单参函?Unary Function)和双参函?Binary Function)三种形式Q它们分别能以f()、f(x)和f(x,y)的Ş式被调用QSTL定义的其他所有函数对象都是这三种概念的强化。如下简单示例展C几UŞ式的实现Q?br />
1、无?Generator)形式 struct counter { typedef int result_type; counter(result_type init=0):n(init){} result_type operator() { return n++;} result_type n; } 2、单?Unary Function)形式 template<class Number> struct even // 函数对象evenQ找出第一个偶?{ bool operator()(Number x) const {return (x&1) == 0;} } // 使用法find_if在区间A到A+N中找到满_数对象even的元?int A[] = {1,0,3,4}; const int N=sizeof(A)/sizeof(int); find_if(A,A+N, even<int>()); 3、双?Binary Function)形式 struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1<s2) < 0;} }; // 使用函数对象ltstrQ输出set容器中A和B的ƈ?const int N=3 const char* a[N] = {"xjz","xzh","gh"}; const char* b[N]= {"jzx","zhx","abc"}; set<const char*,ltstr> A(a,a+N); set<const char*,ltstr> B(b,b+N); set_union(A.begin(),A.end(),B.begin(),B.end(), ostream_iterator<const char*>(cout," "), ltstr());  (tng) (tng) (tng) 容器(container)是一U对?object)Q可以包含ƈ理其它的对象,q提供P代器(iterators)用以定址其所包含之元素。根据P代器U类的不同,容器也分为几中,以Input IteratorP代器的一般containerQ以Forward IteratorP代器的Forward ContainerQ以Bidirectional Iterator P代器的Reversible ContainerQ以Random Access IteratorP代器的Random Access Container。STL定义二种大小可变的容器:(x)序列式容?Sequence Container)和关联式容器(Associative Container)序列式容器包括vector、list和dequeQ关联式容器包括set、map、multiset和multimap。以下示例简单说明部分容器的使用Q?1、vector使用 // A中以元素5为分割点Q分别排序,使排序后5后面的元素都大于5之前的元?后区间不排序)Q?// 然后输出 int main() { int A[] = {7,2,6,4,5,8,9,3,1}; const int N=sizeof(A)/sizeof(int); vector<int> V(A,A+N); partial_sort(V,V+5,V+N); copy(V,V+N,ostream_iterator<int>(cout," ")); cout << endl; } 输出可能是:(x)1 2 3 4 5 8 9 7 6 2、list使用 // 产生一IlistQ插入元素后排序Q然后输?int main() { list<int> L1; L1.push_back(0); L1.push_front(1); L1.insert(++L1.begin,3); L1.sort(); copy(L1.begin(),L1.end(),ostream_iterator<int>(cout," ")); } 输出Q? 1 3 3、deque使用 int main() { deque<int> Q; Q.push_back(3); Q.push_front(1); Q.insert(Q.begin()+1,2); Copy(Q.begin(),Q.end(),ostream_iterator<int>(cout," ")); } 输出Q? 2 3 4、map使用 int main() { map<string,int> M; M.insert(make_pair("A",11); pair<map<string,int>::iterator, bool> p = M.insert(make_pair("C",5)); if(p.second) cout << p.first->second<<endl; } 输出Q? 5、multiset使用 int main() { const int N = 5; int a[N] = {4,1,1,3,5}; multiset<int> A(a,a+N); copy(A.begin(),A.end(),ostream_iterator<int>(cout," ")); } 输出Q? 1 3 4 5 设计新思维
 (tng) (tng) (tng) 设计模?design patterns)、泛型编E?generic programming)和面向对象编E?object-oriented programming)有机的结合v来,便Ş成了(jin)设计新思维。其中,设计模式是经q提炼的?gu)设计?gu)Q对于很多情况下到的问题,它都是合理而可复用的解x(chng)案;泛型~程是一U典?paradigm)Q专注于类型抽象化QŞ成功能需求方面的一个精l集合,q利用这些需求来实现法Q相同的法可以q用于广泛的cd集中Q所谓泛型,是h在多U数据类型上皆可操作的含意;最后同面象对象~程中的多?polymorphism)和模?templates){技术相l合Q便获得极高层次上的h可复用性的泛型lg。泛型组仉先实C(jin)设计模块Q可以让用户指定cd和行为,从而Ş成合理的设计Q主要特Ҏ(gu)灉|、通用和易用?
 (tng) (tng) (tng) policies和policyc,是一U重要的c设计技术,所谓policyQ是用来定义一个类或类模板的接口,该接口由下列之一或全部组成:(x)内部cd定义、成员函数和成员变量。基于policy的类p多小型类(UCؓ(f)policies)l成Q每一个这L(fng)型cd负责单纯如行为或l构的某一斚w。Policies机制由模板和多重l承l成Q它们可以互相؜合搭配,从而Ş成设计戎的多h,通过plicyc,不但可以定制行ؓ(f)Q也可以定制l构?

下面单D例说明泛化思维和面向对象思维在部分设计模式中的运用?

 (tng) (tng) (tng) Singletons设计模式泛化实现 Singleton模式是一U保证一个对?class)只有一个实体,qؓ(f)它提供一个全局讉K炏VSingleton是一U经q改q的全局变量Q既在程序中只能有唯一实体的类型,它的重点主要集中在生和理一个独立对象上Q而且不允生另一个这L(fng)对象?
先让我们看看一般的C++实现的基本手法,下面是实现源码:(x) // Singleton.h文g?class Singleton { public: static Singleton& Instance() { if(!pInstance_){ if(destroyed_){ // 引用是否已经失效 OnDeadReference(); } else { Create(); // W一ơ时创徏实例 } } return *pInstance_; } private: Singleton(); // 止默认构?Singleton(const Singleton&); // 止拯构?Singleton& operator= (const Singleton&);  // 止赋值操?static void Create() // 传加创徏的实例引?{ static Singleton theInstance; pInstance_ = &theInstance; } static void OnDeadReference() { throw std::runtime_error(" 实例被不正当消毁"); } virtual ~Singleton() { pInstance- = 0; destroyed_ = true; } static Singleton *pInstance_; static bool destroyed_; } // Singleton.cpp中静(rn)态成员变量初始化 Singleton* Singleton::pInstance_ = 0; Bool Singleton::destroyed_ = false;  (tng) (tng) (tng) 如上所C,Singleton模式实现中只有一个public成员I(y)nstance()用来W一ơ用时创徏单一实例Q当W二ơ用时?rn)态变量将已经被设定好Q不?x)再ơ创建实例。还默认构造函数、拷贝构造函数和赋值操作符攑֜private中,目地是不让用户用它们。另外,为避免实例意外消毁后再实例化情况Q加入静(rn)态布?yu)(dng)变量destroy_来进行判断是否出错,从而达到稳定性?br /> (tng) (tng) (tng) 从上面一般实现可以看出Singleton模式实现主要在于创徏(Creation)斚w和生存期(Lifetime)斚wQ既可以通过各种Ҏ(gu)来创建Singleton。Creation必然能创建和摧毁对象Q必然要开放这两个相应函数Q将创徏作ؓ(f)独立{略分离开来是必需的,q样你就可以创徏多态对象了(jin)Q所以泛化Singletonq不拥有Creator对象Q它被放在CreationPolicy<T>cL板之中。生命期是指要遵循C++规则Q后创徏都先摧毁Q负责程序生命期某一时刻摧毁Singleton对象?

下面是一个简单的泛化Singleton模式的实?不考虑U程因素) template < class T, template<class> calss CreationPolicy = CreateUsingNew, template<class> class LifetimePolicy=DefaultLifetime, > classs SingletonHolder { public: static T& Instance() { if(!pInstance_) { if(destroyed_) { LifetimePolicy<T>::OnDeadReference(); destroyed_ = false; } pInstance_ = CreationPolicy<T>::Create(); LifetimePolicy<T>::SchedultCall(&DestorySingleton); } return *pInstance_; } private: static void DestroySinleton() { assert(!destroyed_); CreationPlicy<T>::Destroy(pInstance_); pInstance_ = 0; destroyed_ = true; } SingletonHolder(); SingletonHolder (const SingletonHolder &); SingletonHolder & operator= (const SingletonHolder &);  Static T* pInstance_; Static bool destroyed_; };  (tng) (tng) (tng) Instance()是SingletonHolder开攄唯一一个public函数Q它在CreationPolicy、LifetimePolicy中打造了(jin)一层外壟뀂其中模板参数类型TQ接收类名,既需要进行Singleton的类。模板参数内的类模板~省参数CreateUsingNew是指通过new操作W和默认构造函数来产生对象QDefaultLifetime是通过C++规则来管理生命期。LifetimePolicy<T>中有二个成员函数QScheduleDestrution()函数接受一个函数指针,指向析构操作的实际执行函敎ͼ如上面DestorySingleton析构函数QOnDeadReference()函数同上面一般C++中同名函数相同,是负责发现失效实例来抛出异常的。CreationPlicy<T>中的Create()和Destroy()两函数是用来创徏q摧毁具体对象的?

下面是上q泛化Singleton模式实现的用:(x)

1、应用一 class A{}; typedef SingletonHolder<A, CreateUsingNew> SingleA; 2、应用二 class A{}; class Derived : public A {}; template<class T> struct MyCreator : public CreateUsingNew<T> { static T* Create() { return new Derived; } static void Destroy(T* pInstance) { delete pInstance; } } typedef SingletonHolder<A,MyCreator> SingleA;  (tng) (tng) (tng) 通过上面CZ可以看出Q?SingletonHolder采用Zplicy设计实现Q它?yu)Singleton对象分解为数个policiesQ模板参数类中CreationPolicy和LifetimePolicy相当于二个policies装体。利用它们可以协助制作出使用者自定义的Singleton对象Q同时还预留?jin)调整和扩展的空间。由此而得Q泛型组?generic components)Q是一U可复用的设计模板,l合?jin)模板和模式Q是C++中创造可扩充设计的新Ҏ(gu)Q提供了(jin)从设计到代码的简易过渡,帮助我们~写清晰、灵zR高度可复用的代码?

参考文?
  • C++ Primer(W三? --- 潘爱民等?
  • Effective C++(W二? --- 侯捷?
  • More Effective C++ --- 侯捷?
  • Exceptional C++ --- 卓小涛译
  • More Exceptional C++ --- 於春景译
  • 深度探烦(ch)C++对象模型 --- 侯捷?
  • 泛型~程与STL --- 侯捷?
  • C++ STLE序员开发指?--- 彭木根等?
  • 设计模式Q可复用面向对象软g的元?--- 李英军等?
  • C++设计新思维 --- 侯捷{译


木木?/a> 2007-01-04 15:07 发表评论
]]>C++随笔 ?STL[vector]的存储技?原创)http://www.shnenglu.com/mumutou/archive/2007/01/04/17231.html木木?/dc:creator>木木?/author>Thu, 04 Jan 2007 06:26:00 GMThttp://www.shnenglu.com/mumutou/archive/2007/01/04/17231.htmlhttp://www.shnenglu.com/mumutou/comments/17231.htmlhttp://www.shnenglu.com/mumutou/archive/2007/01/04/17231.html#Feedback1http://www.shnenglu.com/mumutou/comments/commentRss/17231.htmlhttp://www.shnenglu.com/mumutou/services/trackbacks/17231.html首先我们先来看Example Code:
#include <vector>
#include <iostream>
#include <memory>
using namespace std;
void main()
{
 (tng)vector<int> v;
// (tng)cout<<v.allocator;
 (tng)v.push_back(0);
 (tng)v.push_back(1);
 (tng)v.push_back(2);
 (tng)v.push_back(3);
 (tng)v.push_back(4);
 (tng)v.push_back(5);
 (tng)cout<<v.max_size();
}
利用VC6.0的内存调?br /> (tng)v.push_back(0);之后
//_Firstq代?0481B40
//_Lastq代?0481B44
//_Endq代?04B1B44
 (tng)v.push_back(1);之后
//_Firstq代?0481B00
//_Lastq代?0481B08
//_Endq代?04B1B08
Z么在执行一ơpush_back之后,q代器全部会(x)变呢?
下面我们看看P.J. Plauger的代?br /> (tng)void insert(iterator _P, size_type _M, const _Ty& _X)
 (tng) (tng){if (_End - _Last < _M)
 (tng) (tng) (tng){size_type _N = size() + (_M < size() ? size() : _M);
 (tng) (tng) (tng)iterator _S = allocator.allocate(_N, (void *)0);
 (tng) (tng) (tng)iterator _Q = _Ucopy(_First, _P, _S);
 (tng) (tng) (tng)_Ufill(_Q, _M, _X);
 (tng) (tng) (tng)_Ucopy(_P, _Last, _Q + _M);
 (tng) (tng) (tng)_Destroy(_First, _Last);
 (tng) (tng) (tng)allocator.deallocate(_First, _End - _First);
 (tng) (tng) (tng)_End = _S + _N;
 (tng) (tng) (tng)_Last = _S + size() + _M;
 (tng) (tng) (tng)_First = _S; }
 (tng) (tng)else if (_Last - _P < _M)
 (tng) (tng) (tng){_Ucopy(_P, _Last, _P + _M);
 (tng) (tng) (tng)_Ufill(_Last, _M - (_Last - _P), _X);
 (tng) (tng) (tng)fill(_P, _Last, _X);
 (tng) (tng) (tng)_Last += _M; }
 (tng) (tng)else if (0 < _M)
 (tng) (tng) (tng){_Ucopy(_Last - _M, _Last, _Last);
 (tng) (tng) (tng)copy_backward(_P, _Last - _M, _Last);
 (tng) (tng) (tng)fill(_P, _P + _M, _X);
 (tng) (tng) (tng)_Last += _M; }}

其中M = 1;
当_End - _Last < _M?p重新分配内存?sh)?哦原来时q样?
[个h认ؓ(f),在方便调试的时?可以把C:\MSDEV\VC98\Include\下面的vector文g中的protectedҎ(gu)public:]
下面我给出在5ơ插入之后其内存分配
push_back(2)
//00481AC0
//00481ACC
//00481AD0
push_back(3);
//00481AC0
//00481AD0
//00481AD0
push_back(4);
//00481B20
//00481B34
//00481B40
push_back(5);
//00481B20
//00481B38
//00481B40
注意没有,_Last - _First之后的明显是size() * 4
[?在VC6.0的STL版本是采用的PJSTL版本,是一U公认最垃圾的STL版本
在C++ Builder中的STL版本是采用的RW版本,Rouge Wave公司
在unix下面GCC采用的是SGI Silicon Graphics Computer System Inc公司STL版本,我认为在可读?可移植性方面最好的一个版本]


]]>
þþAVɫۺ| AVһȾþ| 99ȳ˾ƷȾþ| þһٸ| һɫþ88ձȡۺ| 91þþƷ91þɫ| þҹɫƷ鶹| ޾Ʒþþþϼ| þAV| ŷѹۿþ| Ʒþþþþ³| һþ㽶| þóСƵ| ɫþþۺ| ݺɫۺվþþþþþø| ŷƷž99þڹۿ| þֻǾƷ23| þþþþùƷ| Ů޾Ʒþþۺ| þóۺɫۺ| 99þþƷһ| 㽶þþþ| ޷?Vþò| þþþAVվ | 99þ99þ| ƷVIDEOSSEXþ÷| Ʒþþþ| պŷۺϾþӰԺDs| 2021ھþþƷ| ղƷþþþþþɫ| þþƷ99Ʒ| ƷƵþþþ| ŷպþĻ| Ʒ99þþþþ| þAAAAƬһ| ˾þav| Ʒ99þѹۿ| þþƷAɫ| ¾þƵ| þþƷһ| þAVһ|