现在的位置: 首页 > 综合 > 正文

c++ 笔记

2013年01月31日 ⁄ 综合 ⁄ 共 3288字 ⁄ 字号 评论关闭

C++区分大小写

******名字空间

名字空间引入的目的是将标识符的名字定位在一定范围内以避免发生名字冲突。我们可以从C++编程环境中看出变量名、函数名和类名的暴增。在引入名字空间之前,所有这些名字都在争相获取全局名字空间中的位置,从而引发许多冲突。例如,如果你在程序中定义了一个称为abs()的函数,该函数会覆盖标准的库函数abs(),这是因为这两个函数名都存储在全局名字空间中。当在同一个程序中使用两个或多个有第三方提供的库时,各种名字冲突会被混在一起。这种情况下,有可能发生以下情况,即:一个库定义的名字与其他库定义的名字发生冲突。对于类名而言,这种情况尤其令人棘手。

&<60;&<60;&<60;&<60;关键字namespace的创建就是为了解决这些问题。因为该关键字把名字的可见性定位在声明它的范围内,所以可以允许在不同的上下文中使用相同的名字,而且不会引起冲突。在引入namespace之前,整个C++库定义在全局名字空间(当然,他是唯一的名字空间)内。由于namespace的引入,C++库现在定义在自己的称为std的名字空间中,从而减少了发生名字冲突的机会。

namespace定义了一个作用域,一般的形式如下:

namespace name{

//declarations

}

标准C++把整个库定义在自己的名字空间中,该名字空间称为std。

******cin/cout

cin/cout提供了控制符dec、hex和oct,分别用于指示cout以十进制、十六进制和八进制格式显示整数。默认格式为十进制。可以通过如下方法修改显示格式:

cout << hex;

cout << a; //如果a定义为char类型则显示字符

***string类

使用string类存储字符串比使用数组简单方便,要使用string类,必须在程序中包含头文件string。使用string的优点和技巧:

1.可以将一个string对象赋给另一个string对象,不能讲一个数组赋给另一个数组。

2.可以使用操作符+将两个string对象合并起来,还可以使用操作符+=将一个字符串附加到一个string对象的末尾。

3.string类具有自动调节大小的功能,能避免内存覆盖等错误。

4.str1.size()可以表示string对象str1的大小。

******const与volatile

const int * ps = &a; //a pointer to const int

int * const finger = &b; //a const pointer to int&<60;

虽然不能通过*ps修改a,不过可以直接修改a。

******函数指针

double (*pf) (int); //pf points to a function that returns double

double *pf (int); //pf() is a function that returns a pointer-to-double

******引用

int rats =&<60;101;

int & rodents = rats; //rodents is a&<60;reference

注意:引用不能先声明在赋值,必须在声明是进行初始化,就像const指针一样。

一个有趣的例子:

const sysop & use(sysop & sysopref)&<60; //这里sysop是一个结构体

{......

return sysopref;

}

int main()

{.....

sysop looper= {.........};&<60;&<60; //声明并初始化looper

use(looper);

sysop copycat;

copycat = use(looper);

}

改程序尝试了3个新的领域。

第一是使用指向结构的引用。

use(looper);

该函数调用将结构looper按引用传递给use(),使得sysopref成为looper的别名。

第二个新领域是将引用作为返回值。

通常,返回机制将返回值复制到临时存储区域中,随后调用程序将访问该区域。然后,返回引用意味着嗲用程序将直接访问返回值,而不需要拷贝。通常,引用将指向传递给函数的调用,因此调用函数实际上是直接访问自己的一个变量。例如,在这个例子中,sysopref是looper的引用,因此返回值是main()中的原始looper变量。看下面一行代码:

copycat = use(looper);

如果函数use()返回一个结构,sysopref的内容将被复制到一个临时返回存储单元中,然后该临时返回存储单元的内容将被复制到copycat中。这显示了返回指向结构的引用而不是结构的优点之一:效率更高。

第三个新领域是,使用函数调用来访问结构的成员:

cout << "use(looper):" << use(looper).used ;

由于函数use()返回一个指向looper的引用,因此上述代码与下面两行代码等效:

use(looper);

cout << "use(looper):" << looper.used;

表示use(looper).used访问looper的成员used。如果该函数返回一个结构而不是指向结构的引用,则这些代码返回的将是looper的临时拷贝的used成员。

返回引用时,应避免返回当函数终止时不再存在的内存单元引用。为避免这个问题,最简单的方法是,返回一个作为参数传递给函数的引用。

为何将const用于引用返回类型?

函数use()的返回类型为const sysop &,它意味着你不能使用它返回的引用来直接修改它指向的结构。

******结构和类

类和结构的唯一区别在于:默认时,结构的所有成员是公有的,而类的所有成员是私有的。除此以外,类和结构是等价的。

******友元函数

准许非成员函数通过使用友元(friend)访问类的私有成员是可能的。友元函数可以访问类的所有私有成员和保护成员。要在类中声明一个友元函数,在类中包含它的原型,只需在其中之前加上关键字friend。例如:

class myclass{

....

public:

friend int sum(myclass x);

};

int sum(myclass x)

{............}

例子中,函数sum()不是myclass的成员,调用sum()时也不使用点运算符。

使用友元函数的好处:

1,友元对重载某些运算符很有好处。

2,友元函数使得够着某些类型的I/O函数更加容易。

3,当两个或多个类包含与程序其他部分相关的相互关联的成员时,友元函数即为所求之物。

使用友元函数有两个重要的限制:

1,派生类不继承友元函数。

2,友元函数不能有存储类标识符,即,它们不能被定义为静态的(static)或外部的(extern)。

******静态类成员

当把static置于一个成员变量的声明之前时,编译器被告知该变量只存在一个副本,且该类的所有对象将共享这个变量。创建第一个对象前,所有静态变量都被初始化为0。

当在一个类内声明一个静态数据成员时,你不是在定义它(即,没有为其分配存储空间)。相反,必须在类外对静态数据成员提供全局定义。例如

int myclass::a; //其中a为myclass中定义的一个静态整型变量

静态成员变量在它的类的任何对象创建之前就存在了。

静态成员变量的一个用途就是对一些被类的所有对象使用的共享资源提供访问控制。

成员函数也可以声明为静态。对静态成员函数有一些限制:

1.静态成员函数只能引用这个类的其他静态成员(当然可以访问全局函数和数据)。

2.静态成员函数没有this指针。

3.同一个函数不能有静态和非静态两种版本,静态成员函数也不可以是虚函数。最后,他们不能被声明为const或volatile。

实际上,静态成员函数的应用是有限的,使用它的好处是在实际创建任何对象之前可以“预初始化”私有的静态数据。

******作用域分辨符::

作用域分辨符的另外一个用途:它允许引用一个跟封闭作用域里声明的局部变量同名的全局变量。就是说,如果作用域里声明了一个局部变量,而域外也声明了一个相同名字的全局变量。要想在域内引用全局变量只需要在变量前加上::就可以了。

 

抱歉!评论已关闭.