??xml version="1.0" encoding="utf-8" standalone="yes"?>
内存的三U分配方式:
1Q?nbsp;从静态存储区分配Q此时的内存在程序编译的时候已l分配好Qƈ且在E序的整个运行期间都存在。全局变量Qstatic变量{在此存储?/p>
2Q?nbsp;在栈区分配:相关代码执行时创建,执行l束时被自动释放。局部变量在此存储。栈内存分配q算内置于处理器的指令集中,效率高,但容量有限?/p>
3Q?nbsp;在堆区分配:动态分配内存。用new/malloc时开辟,delete/free旉放。生存期qh定,灉|。但有内存泄露等问题?/p>
常见内存错误及对{?/p>
1Q?nbsp;内存分配未成功,却被使用?/p>
对策Q用内存之前检查是否分配成功。用p!=NULL判断?/p>
2Q?nbsp;内存分配成功Q未初始化就被用?/p>
内存的缺省值没有统一的标准。大部分~译器以0作ؓ初始|但不完全是?/p>
对策Q内存初始化时赋初倹{?/p>
3Q?nbsp;内存操作界?/p>
对策Q只能是心了?/p>
4Q?nbsp;释放了内存,仍然使用?/p>
Q?Q?nbsp; 使用昄delete和free的野指针?/p>
对策Q释攑֮内存Q将指针|ؓNULL?/p>
Q?Q?nbsp; 使用隐式delete和free的野指针。主要是指函数返回指向栈内存的指针或引用?/p>
对策Q当然是不要q回可以了?/p>
5Q?nbsp;未释攑ֆ存,D内存泄露?/p>
用new/malloc开辟了内存Q没用delete/free释放.
对策Qnew和delete的个C定相同;malloc和free的个C定相同;new[]和[]delete一定对应?br>
CZ1Q返回指向栈I间的指?br>
输出l果Q?br>q
Hello World!
Hello World!
CZ2Q?/span>new?/span>delete虽然对应Q但delete释放不成?/span>
q行旉误?/span>P虽然是动态开辟的内存Q但在第二条语句?/span>p已经指向了静态存储区上的地址Q而对指向静态存储区的指针是不能?/span>delete释放的。此时不仅运行时错误Q还有内存泄霌Ӏ?/span>
Portotype: int printf(char* str, const char* format, parameters);
Writes into the array pointed by str a C string consisting on a sequence of data formatted as the format argument specifies. After the format parameter, the function expects at least as many additional arguments as specified in format.
This function behaves exactly as printf does, but writing its result to a string instead of stdout. The size of the array passed as str should be enough to contain the entire formatted string .
Return value:
On success, the total number of characters written is returned. This count does not include the additional null-character automatically appended at the end of the string.
对于指针a,delete a之后Q指?/span>a 的地址仍然是原来的地址(q不是NULL)Q只不过所指向的对象被释放了,此时指针存放的gؓ随机的,q译器定?br>
使用宏和内联函数都可以节省在函数调用斚w的时间和I间开销。二者都是ؓ了提高效率,但是却有着显著的区别:
(1)、在使用Ӟ宏只做简单的预处理器W号?字符?中的单替换。而内联函数可以进行参数类型检查,且具有返回?也能被强制{换ؓ可{换的合适类??br>(2)、内联函数首先是函数Q函数的许多性质都适用于内联函?如内联函数可以重??br>(3)、内联函数可以作为某个类的成员函敎ͼq样可以使用cȝ保护成员和私有成员。而当一个表辑ּ涉及到类保护成员或私有成员时Q宏׃能实C(无法this指针攑֜合适位|??/p>
可以用内联函数完全替代宏?br>但是在用内联函数时也要注意Q作为内联函敎ͼ函数体必d分简单,不能包含循环Q条Ӟ选择{复杂结构,否则不能作ؓ内联函数?br>实际上,~译器的优化pȝ会自动将一些简单函数变成内联函数。而一些复杂的函数Q即使指定ؓ内联Q编译器也会自动当作普通函数?/p>
文章出处QDIY部落(http://www.diybl.com/course/3_program/c++/cppxl/20081216/154041.html)
?/span>Z么用static成员而不是全局对象Q?/span>
---- static对象名字在类作用域中Q可以有效避免命名冲H,q且清晰昄E序意图?/span>
---- 可以实施装Q?/span>static成员可以定义?/span>privateQ而全局对象不可以)
?/span> 如何调用Q?/span> ---- class A a; A::static_mem; a.static_mem;
?/span> 声明和定?/span>
---- static成员函数在类定义体内部外部定义均可。在cd义体外定义时不加Q不可以加)static修饰?/span>
---- static数据成员必须在类定义体外部定义(正好一ơ)(在类定义体外声明q定?/span>)
class A{public : static int n;} int A::n = 10;
---- const static数据成员可以Q也可以不)在类定义内初始化Q但必须在类定义体外部重新声明(不可以加static修饰W,不可以赋初|
?/span> static数据成员其他Ҏ(gu):
----一般地Q在cȝ内部不能有该cȝ型的变量Q或函数形参Q,最多只能有该类cd的指针或引用做变量类型(或函数Ş参). static数据成员则不受这个限制?/span>
---- cȝstatic数据成员可以作ؓ函数默认实参
---- static成员的承:如果基类有static成员Q则整个l承层次中只有一个这L成员。每个static成员L只有一个实例?br>
1.多重l承下的cM用域名字查找规则Q?/strong>W一步,~译器找C个匹配的声明。如果匹配的声明不止一个,则导致二义性,出错Q第二步Q编译器定扑ֈ的名字是否合法?
避免二义性的Ҏ(gu)Q在解决二义性的zcM定义函数的一个版本?
2. 采用虚承的Ҏ(gu)可以有效减少二义性?/strong>定义虚承的Ҏ(gu)Q在z列表中包?#8220;virtual”?
虚承中名字查找Ҏ(gu)。设查找函数funcQ(1Q如果在每个路径中func表示同一基类成员Q则没有二义性,因ؓcd享该成员的单个实例。(2Q如果在某个路径中func是虚基类的成员,而在另一路径上是后代zcȝ成员Q也没有二义性,因ؓ特定zcd例的优先U高于共享虚基类实例。(3Q如果沿每个l承路径func表示后代zcȝ不同成员Q则h二义性?
3.虚承的Ҏ(gu)初始化方?/strong>。通常Q每个类只初始化自己的直接基cR但在虚l承中也q样q行的话Q可能会多次初始化虚基类?
由最低层Q非虚承)zcȝ构造函数初始化虚基cR(2QQ何直接或间接l承虚基cȝcM般也必须虚基cL供自q初始化式Q以提供自n对象初始化用?
class ZooAnimal{...};
class Bear: public virtual ZooAnimal{...};
class Raccoon: public virtual ZooAnimal{...};
class Endangered{...};
class Panda: public Bear,public Raccoon,public Endangered{...};
在上面的例子中,Panda构造函数初始化PandaQZooAnimal,Bear,Raccoon,Endangered部分Q供Panda对象使用。BearQor RaccoonQ构造函数初始化Bear(or Raccoon),ZooAnimal部分供Bear(or Raccoon)对象使用.
4. 虚承的构造函数次?/strong>。先是全部直接基cȝ虚基cȝ构造函数按声明的顺序,然后是非虚基cd数按声明的顺序运行?img height=1 alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=982263437555584821&page=RSS%ef%bc%9a%e5%a4%9a%e9%87%8d%e7%bb%a7%e6%89%bf%e4%b8%8e%e8%99%9a%e7%bb%a7%e6%89%bf&referrer=" width=1 border=0>
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!267.entry
]]>
template<class cl, class T>
cl func(cl* cl_p, T value)
{
//cl::size_type * value; // If cl::size_type is a type, then a declaration
// If cl::size_type is an object, then a multiplication
typename cl::size_type *value;
}
2. 非类型模板Ş参的使用: 模板非类型Ş参是模板定义内部的常量?(在需要常量表辑ּ的时?可以用非cd形参,如定义数l的长度)?
因ؓ非类型模板Ş参需要传递的是常量表辑ּQ所以不支持一般的隐式cd转换?
template<class T, size_t N> void fcn(T (&cl)[N]) {...}
int x[20];
fcn(x);
3. 模板何时实例化?函数声明Q定义对象的引用和指向对象的指针都不会实例化。定义类对象或调用函数时实例化?
4.friend模板声明依赖性:Q?Q?当授予对l定模板所有实例的讉K权时Q在作用域中不需要存在该cL板或函数模板的声明。编译器友元声明也当作cL函数的声明对待;Q?Q想要限制对特定实例化的友元关系Ӟ必须在可以用于友元声明之前声明类或函数?
5.对于不同参数的函数模板用相同参数可以调用么?可以Q会调用隐式转换?
#include<iostream>
using namespace std;
template<typename T1, typename T2>
void print(const T1 &v1, const T2 &v2) //参数cd不同
{
cout << "T1 = " << v1 <<endl;
cout << "T2 = " << v2 <<endl;
}
int main()
{
print(1,2); //ok
int a=1; return 0;
int b=2;
print(a,b); //okQŞ参类型相?/font>
}
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!266.entry
]]>
//template.cpp
template<typename T>
void print(const T &v)
{
cout << "T = " << v <<endl;
}
//template.h
#ifndef TEMPLATE_H
#define TEMPLATE_H
template<typename T>
void print(const T &v);
#include "template.cpp"
#endif
//main.cpp using namespace std;
int main() 2. 分别~译模型Qseperate compilation modelQ?函数声明和类定义攑֜头文件中Q带export关键字的函数定义和类声明攑֜源文件中。源文g含头文g。(不知道理解的对不对,用的~译器不支持分别~译Q暂时无从判断了Q?
//the template definition goes in a separately-compiled source file
export template<typename T>
T print(const T&v) /*...*/
//class template header goes in shared header file
template <class T> class cl{...};
//cl.cpp implementation file declares cl as exported
export template <class T> class cl;
#include "cl.h"
//cl member definitions
#include<iostream>
#include "template.h" //#include"template.cpp" 用这条命令代替也可以?/font>
{
print(1); //ok
return 0;
}
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!265.entry
]]>
基类析构函数应定义ؓvirtualQ复制操作符一般定义ؓ非virtual
在基cL造函数和析构函数中,派生类对象当作基类cd对象对待。(因ؓ在这两个函数的运行过E中Q对象不是一个完整的zcȝ型)
cȝ复制控制的三法则有个例外Q定义(I)虚构够函数时可以不定义构造函数和赋值函数?img height=1 alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=982263437555584821&page=RSS%ef%bc%9a%e5%9f%ba%e7%b1%bb%e7%9a%84%e5%a4%8d%e5%88%b6%e6%8e%a7%e5%88%b6%e5%87%bd%e6%95%b0&referrer=" width=1 border=0>
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!264.entry
对于后代cd用户代码Q?
publicl承Ӟ后代cd用户代码都可以?
protectedl承Ӟ后代cd以,用户代码不可以?
privatel承Ӟ后代cd用户代码都不可以?img height=1 alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=982263437555584821&page=RSS%ef%bc%9a%e6%b4%be%e7%94%9f%e7%b1%bb%e5%88%b0%e5%9f%ba%e7%b1%bb%e8%bd%ac%e6%8d%a2%e7%9a%84%e5%8f%af%e8%ae%bf%e9%97%ae%e6%80%a7&referrer=" width=1 border=0>
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!263.entry
2.zcd能通过zcd象访问其基类的protected成员Q派生类对其基类cd对象的protected成员没有Ҏ(gu)讉K权限?
#include<iostream>
using namespace std;
class Base
{
public:
Base():i(0),j(0){};
protected:
int i;
private:
int j;
};
class Derived:public Base
{
Derived():Base(){};
print(const Base &b, const Derived &d)
{
int num = i;
//num = b.i; //error. cannot access protected member declared in class 'Base'
num = d.i;
//num = d.j; //error. cannot access private member declared in class 'Base'
};
};
int main()
{
return 0;
}
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!262.entry
M时候编译器都会合成析构函数Qƈ且合成的析构函数Mq行?
撤销容器Q标准库容器和内|数l)是按逆序q行的?
内存泄漏QMemory leakQ:删除指向动态分配内存的指针p|Q因而无法将该块内存q还l自由存储区Q这L删除动态分配内存失败称为内存泄漏?/font>
只有当删除指向类对象的指针时才会q行该对象的析构函数。如果不删除指针Q则对象一直存在,D内存泄漏?
三法则(rule of threeQ:如果c需要析构函敎ͼ则也需要赋值操作符和复制构造函数?img height=1 alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=982263437555584821&page=RSS%ef%bc%9a%e6%9e%90%e6%9e%84%e5%87%bd%e6%95%b0%ef%bc%88%e5%86%85%e5%ad%98%e6%b3%84%e6%bc%8f%ef%bc%8c%e4%b8%89%e6%b3%95%e5%88%99%ef%bc%89&referrer=" width=1 border=0>
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!255.entry
]]>
初始化列表:通常使用初始化是Z提高效率Q它直接调用与实参匹配的构造函数。【因Z般在构造函C内的复制也经q初始化-->计算赋?font color=#404040>Q此时会调用复制构造函敎ͼ两个阶段】;特别的有些时候只能用初始化列表,即不能赋值的参数Q如Qconst或引用类型的成员Q没有默认构造函数的cȝ型成员。初始化列表中变量的初始化顺序是先声明的先初始化.
class cl1{ private: const int ci; int &ri;}; //ci,ri只能在初始化列表中进行初始化?/font>
默认构造函敎ͼ全部形参是默认实参的构造函C是默认构造函数?/font>
只要自己定义了(L的)构造函敎ͼ~译器就不会为我们合成默认构造函数?
复制构造函敎ͼ单个形参为本cȝ型对象的引用的构造函数。对于不支持复制的类型(如IOcdQ不能用复制构造函数。如果自己定义了复制构造函敎ͼ而不是构造函敎ͼ卻I只定义构造函敎ͼ但没有定义复制构造函敎ͼ则编译器合成复制构造函敎ͼQ则~译器不会合成复制构造函数。【复制构造函数需要特别注意指针成员,以后说明?/font>
ifstream file1("filename1"); //ok, direct initialization.
ifstream file2="filename2"; //error
如何防止复制Q?/font>可以通过复制构造函数声明ؓprivate来禁止普通函敎ͼ非成员,非友元函敎ͼ的访问;可以通过声明一个private复制构造函数而不对其定义来禁止成员函数和友元函数的访问?img height=1 alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=982263437555584821&page=RSS%ef%bc%9a%ef%bc%88%e5%a4%8d%e5%88%b6%e3%80%81%e9%bb%98%e8%ae%a4%ef%bc%89%e6%9e%84%e9%80%a0%e5%87%bd%e6%95%b0&referrer=" width=1 border=0>
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!254.entry
]]>
mutable数据成员QQ何函敎ͼ包括cconst成员函数Q都可以修改mutable数据成员?
explicit构造函敎ͼ声明时指定,定义时不允许重复指定为explicit。作用:防止在需要隐式{换的上下文中使用构造函数?
friend成员Q?/font>非类成员可以讉KcȝU有成员。需要特别注意友元声明和作用域。如果想(其他cȝQ成员函数设为友元,必须先声明;而如果想(其他Q类或非成员函数设ؓ友元Q则不必预先声明?
static数据成员Q?/font>static数据成员不用构造函敎ͼ在类的外部定义,定义时进行初始化?
static成员函数Q?/font>声明时指定staticcdQ定义时不用重复声明。没有this指针?
const static数据成员Q?/font>一般地cȝstatic数据成员不能在类的内部定义。有例外是可以用常量表辑ּ初始化const static数据成员Q不q即使这样也需要在cd义体的外部进行该const static数据成员的定义?
static成员不是cd象的l成部分Q非static数据成员不能是该成员所属的cȝ型,而只能是对应的指针和引用Q而static成员则可以是该成员所属的cȝ型?/font>
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!252.entry
]]>
queue priority_queue stack
队列 ?nbsp; ?
deque vector deque //默认相关联容器类?/font>
push_front 随机讉K ?nbsp; //对关联容器的要求
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!251.entry
]]>
1.插入Q?/font>一般插入是在给定的q代器位|前Q这hendq代器也课正常编译。插入的元素cd必须与c的类型完全一栗?
void c.push_back(t);
void c.insert(p,b,e);
void c.insert(p,n,t);
iter c.insert(p,t);
2.赋?/font>Q?font color=#ff00ff>c1= c2
c.assign(b,e); c.assign(n,t) //允许不同的容器,不同的元素,只要元素cd兼容?/font>
3.讉KQ?/font>c.back(); c.front();
c[n]; c.at[n]; //q样的下标访问容易越界。后者越界是抛出 out_of_range异常?/font> 4.删除Q?font color=#ff00ff>iter c.erase(p); iter c.erase(b,e);
void c.clear();
void c.pop_back();
c.pop_front();
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!250.entry
]]>
file1.cpp type v1;
const type v2; //now,v2 is a local variable.
extern const type v3;//now,v3 is a global variable. must add 'extern'~.
file2.cpp type v1; // error.redeclaration.
extern type v1; //ok.
type v2; //ok.but not equivalent to v2 in file1.cpp
const type v3; // ok.but not equivalent to v3 in file1.cpp
extern const type v3; //ok.equal to v3 in file1.cpp.
2. const引用Q?/font>const type& v; 是指向const对象的引用。非const引用只能l定C该引用同cd的对象。而const引用则可以绑定到不同但相关的cd那个的对象和叛_{?
double dv = 1.0; const int &iv = dv; ~译时等价于
int temp = dv; const int &iv = temp; //可以看出对iv的修改ƈ不会影响dv的?
3.const与指?/font>Q(1Q?指向const对象的指? const type* v; 有时Ctype const* v;可以修改指针Q但不能直接通过该指针修Ҏ(gu)针指向的对象。(可以通过定义非const指针指向该对象,从而修改其|Q?Q?font color=#ff0000>const指针: type *const v;可以修改指针指向的对象,但不能修Ҏ(gu)针本w。(3Q?font color=#ff0000>指向const对象的const指针
4.const与一般函敎ͼ (1) const type1 func(type2 v); 函数q回gؓconst; (2) type1 func(const type2 v);形参为const变量。因为Ş参不是引用,不修改实参的|所以此时的const不v特别的作用;Q?Q?font color=#ff00ff>type1 func(const type& v); 形参为const引用Q不修改传递到形参的实参倹{?指针时相同,不修Ҏ(gu)针指向的对象的倹{?
5.const与类成员函数Q常量成员函敎ͼQtype func(type v) const;{h(hun)于type func(const *this,type v) const; 它是值this指针是指向const对象的指针,q个函数不改变调用该函数的对?font color=#404040>。(备注Q事实上是不可以昄使用this指针作ؓ形参的,但可以在函数体中昄C用this指针。)
6.const与P代器Q?/font>vector<type>::const_iterator it; const vector<type>::iterator iter; it指向的元素不能修改,iter指向的元素可以修改,但P代器本n不能修改?
7.const与容器: const vector<type> vec; 需要注意此时定义的容器q代器必Lconst_iterator型?img height=1 alt="" src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=982263437555584821&page=RSS%ef%bc%9aconst%e9%99%90%e5%88%b6%e7%ac%a6&referrer=" width=1 border=0>
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!243.entry
]]>
2.引用形参是实参的别名Q从而对形参的操作改变实参倹{用途:W一Q大型的参数通过复制初始化效率低时用引用参数Q第二,对于一些不能复制初始化的参敎ͼW三Q可以通过增加形参q回额外的信息?注意Q?/font>type function(type2 v) ?type function(const type2 v)是不同的?/font>
3.const& :一般不需要修改实参时用const引用。这主要是考虑到非const引用形参的如下缺点:W一Q传递的实参必须与Ş参类型完全相同,而不包含可以隐式转换的类型;W二Q传递的实参不能是constQ右倹{?/font>
4.指向指针的引?/font> type* &vQ?/font>
5.Q?)非引用数lŞ?/font>Q?font color=#ff00ff>int*, int[],int[n]?/font>q三个是{h(hun)的,都传递指向第一个元素的指针。这样容易生越界。如何防止越界呢Q第一Q通过l束标记数l的l束Q如C风格字符ԌW二Q用标准库规范,传递第一个和最后一个的下一个元素的指针做参敎ͼW三Q显CZ递数l大的形参?/font>
5.Q?Q?font color=#ff0000>引用数组形参Q?font color=#ff00ff>type (&arr)[n]Q?/font> 注意两点Q一是,圆括h必须的,因ؓ下标q算W的优先U更高;二是Q表C数l元素个数的n是必ȝQ因为引用是数组别名Q而数l是固定长度的?/font>
6.默认实参Q第一要考虑位置Q第二,如果提供实参Q则它覆盖默认的实参倹{?/font>
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!242.entry
]]>
string str1("Hello!"); //ok.
char *str2 = str1; //error.
char *str3 = str2.c_str(); //ok. but not quite.
//注意c_str()q回的数据类型是const char
const char *str4 = str2.c_str(); //ok.
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!232.entry
可以采用 new type[]() 由内|类型的默认值初始化Q注意不能在圆括号内写入值初始化?
但是当是单个对象定义时可以: new type(value) 是有效的
文章来源:http://liyuxia-life.spaces.live.com/Blog/cns!DA1B364675ACF35!231.entry