您的位置:首页 > 编程语言 > C语言/C++

C++中双冒号(::)和冒号(:)的用法

2015-09-10 16:11 489 查看
一、冒号(:)的用法

1、表示结构体内位域的定义(即该变量占几个bit空间)

typedef struct _xxx

{

unsigned char a:6;

unsigned char b;

}XXX;

2、构造函数后面的冒号起分隔作用,是类给成员变量赋值的方法,初始化列表,更适用于成员变量的常量const型。在构造函数后面紧跟着冒号加初始化列表,各初始化变量之间以逗号(,)隔开,例如:

class
myClass

{

public :

myClass();// 构造函数,无返回类型,可以有参数列表,这里省去

~myClass();// 析构函数

int
a;

const int b;

}

myClass::myClass():a(1),b(1) // 初始化列表

{

}

上面的例子展示了冒号的这个用法,下面对这个用法进行几点说明:

1)初始化列表的作用相当于在构造函数内进行相应成员变量的赋值,但两者是有差别的。

在初始化列表中是对变量进行初始化,而在构造函数内是进行赋值操作。两都的差别在对于像const类型数据的操作上表现得尤为明显。我们知道,const类型的变量必须在定义时进行初始化,而不能对const型的变量进行赋值,因此const类型的成员变量只能(而且必须)在初始化列表中进行初始化,即下面的代码将会出错:

myClass::myClass()

{

a = 1;// 没错,效果相当于在初始化列表中进行初始化

b = 1;// 出错,const变量不能进行赋值操作;

}

2)初始化的顺序与成员变量声名的顺序相同。

先看一下下面的程序:

myClass::myClass():b(1),a(b)

{

}

这样的执行结果a,b各是多少呢?b=1,a=1?不是,b=1而a是个随机数。这一点是相当重要的哦,一般在初始化列表中进行初始化时,初始化的顺序应与声明的顺序保持一致,防止出现不必要的错误。

3)对于继承的类来说,在初始化列表中也可以进行基类的初始化,初始化的顺序是先基类初始化,然后再根据该类自己的变量的声明顺序进行初始化。

3、声明基类。

假设我们重新定义一个类,继承自myClass类。定义方式如下:

class derivedClass : public myClass

{

// 略去

}

这里的冒号起到的就是声名基类的作用,在基类类名前面可以加public/private/protected等标签,用于标识继承的类型,也可以省略,省略的话,用class定义的类默认为private,用struct定义的类默认为public,至于具体各个标签有什么区别这里就不说了。

与初始化列表一样的,这里也可以声名多个基类,各基类之间用逗号(,)隔开

4、条件语句(?
:)

与?构成条件语句,作用相当于if else,如下;

int a,b,c;

a=3;

b=2;

c=a>b?a:b; // 如果a>b成立,则反a赋给c,否则把b赋给c

条件语句的结构为:

条件表达式?表达式1:表达式2

当条件表达式为true时,表达式的值为表达式1的值,否则为表达式2的值。

5、语句标签

通常跟goto配合使用,如:

step1: a = f1();

....

goto step1;

这种作法也不是很推荐,原因在于它破坏了语句的顺序执行,这样的代价大家应该清楚吧。不过存在即为合理嘛,既然它还存在,肯定还是有它的用处有它的好处的,比如说,多层嵌套的退出(会比break continue直观一点吧),也可以避免重复代码之类之类的。

6、switch语句中case后。

7、汇编指令模板

可以参考一下:http://developer.e800.com.cn/articles/2006/43/1144846933898_1.html

二、双冒号(::)的用法

1、表示“域操作符”

例如:声明了一个类A,类A里声明了一个成员函数void f(),但没有在类的声明里给出f的定义,那么在类外定义f时, 就要写成void
A::f(),表示这个f()函数是类A的成员函数。

2、直接用在全局函数前,表示是全局函数

例如:在VC里,你可以在调用API 函数里,在API函数名前加::

3、表示引用成员函数及变量,作用域成员运算符

例如:System::Math::Sqrt() 相当于System.Math.Sqrt()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: