1、C++单冒号的含义
(1)类后冒号,表示继承
【类名:public 类名】
//单继承
class A:public B
B是基类,A是B的派生类,即类A按public模式继承类B。
//多继承
class A:public B, public C
继承的三种模式(public,protected,private),以
小范围
为准。
若是public继承,则public和protected成员分别被继承为子类的public和protected成员,若是protected继承,则public和protected成员均被继承为子类的protected成员。private继承,则public和protected成员均被继承为子类的private成员。
《C++规范》:规则6.9 使用public继承而不是protected/private继承
(2)冒号后面,表示括号赋值
【变量类型:变量名(赋的值)】
// 在程序中定义变量并初始化的机制中,有两种形式,一个是我们传统的初始化的形式,即赋值运算符赋值,还有一种是括号赋值,如:
char b='r';//赋值运算符赋值
char b('r');//括号赋值
注意:括号赋值只能
在变量定义并初始化
中,不能
用在变量定义后
再赋值。
【函数名(形参名):变量名(形参名)】
A(int aa, int bb):a(aa),b(bb){}
相当于
A(int aa, int bb)
{
a=aa;
b=bb;
}
(3)构造函数定义时,后的冒号,表示初始化列表
【类名::构造函数(形参表):变量名(变量的初始化参数){函数体}】
//函数定义时,后加一个冒号,表示使用初始化列表来初始化字段
Line::Line(double len): length(len) // 相当于length=len
{
cout<<"Object is being created, length = "<<len<<endl;
}
//上面的语法等同于如下语法:
Line::Line(double len)
{
length = len;
cout << "Object is being created, length = " << len << endl;
}
//多个字段 X、Y、Z 初始化,逗号分隔
C::C(double a, double b, double c):X(a), Y(b), Z(c){...}
// 相当于X=a,Y=b,Z=c
四种情况下应该使用初始化表达式来初始化成员:
1:初始化const成员
2:初始化引用成员
3:当调用基类的构造函数,而它拥有一组参数时
4:当调用成员类的构造函数,而它拥有一组参数时。
为什么要冒号后初始化?
C++":"后初始化的机制,使引用和常量数据成员变为可能的
解释
class Student
{
public :
Student()
protected:
const int a;
int &b;
}
Student::Student(int i,int j)
{
a=i;
b=j;
}
在Student类中有两个数据成员,一个是常量数据成员,一个是引用数据成员,并且在构造函数中初始化了这两个数据成员,但是这并不能通过编译,因为常量初始化时必须赋值,它的值是不能再改变的,与常量一样引用初始化也需要赋值,定义了引用后,它就和引用的目标维系在了一起,也是不能再被赋值的。所以C ++":"后初始化的机制,使引用和常量数据成员变为可能的,Student类的构造函数应为:
Student::Student(int i,int j):a(i),b(j)
{
}
(4)构造函数使用时,后面的冒号表示初始化【其实还是初始化】
【B的构造函数名(参数表):A的构造函数名(参数表)】
class A
{
public:
int x;
A(int a=0){x=a};
};
class B1:publicA
{
public:
int y1;
B1(int a=0,int b=0):A(b) //就是这句
{ y1=a; }
};
请问那句后面的“:A(b)”代表什么啊,为什么要跟在B1基类的构造函数后面?
答:A(b)实际上是做的是用b初始化A的成员x;即x=b; 是初始化列表方式。
参考:
https://www.cnblogs.com/muyi23333/articles/13515792.html
2、C++双冒号::含义(范围解析运算符)
(1)作用域分解运算符
【返回值 类名::成员函数名(参数表){函数体}】
// 类的成员函数定义,一般用于在.h文件中声明函数,在.c文件中定义函数。
int A::add(int a, int b){return a+b;} // 用::定义
class A{ //声明
public:
int a_var;
int add(int a, int b);
int add(int a);
}
(2)类实例的成员(不带类名)
【::成员名】
int A::add(int a){
return a+::a_var; // 当前类实例的成员变量
}
(3)类的成员
【类名::成员名】
A::a_var; //怎么用呢?
(4)全局作用域
【::全局变量名】
// 当全局变量和局部变量重名时,就用::表示全局变量,以区分。
int a;
void f(int a){
int a = ::a;
}
(5)命名空间【不理解?】
参考:
https://blog.csdn.net/qq_42362891/article/details/116197294
https://blog.csdn.net/weixin_45525272/article/details/107482219
3、virtual
析构函数需要声明为virtual
的条件
:
当定义的类中析构函数外
的其他函数有virtual函数
时,这时需要将此类的析构函数定义为virtual函数。
virtual析构函数好处
:
当父类指针指向子类对象时,执行释放操作,子类对象也会被释放掉
。
当定义析构函数为virtual函数时需要知道当前类是否还有子类,如果没有子类
,则可以
将其析构函数不定义为virtual函数
,否则则定义为虚函数。
含有virtual的函数其对象的体积会增加,因为它多了一个vptr指针,所以C++的Point对象就不能和其他语言有着一样的声明结构了,因为也不再具有可移植性。
参考:
https://www.cnblogs.com/jiayouya-susu/p/11962694.html
10、术语
类的数据成员=类的成员变量
范围解析运算符 ::
作者:西伯尔
出处:http://www.cnblogs.com/sybil-hxl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。