C++之几个最常

1.同类对象间的数据共享——静态成员

静态数据成员
声明静态数据成员要采用关键字static;
类静态数据成员的定义和初始化
定义:static 数据类型 成员名;
初始化:数据类型 类名::静态数据成员名=初始值;
注意静态数据成员必须在文件作用域的某个地方用类名限定符对静态数据成员定义并初始化。
class Student
{
private:
int num;
char name[];
public:
static int count;//用于计数的静态变量(这里就是用来计数学生的个数的)
Student(){count++;}
Student(char*,int _num=0);
~Student(){count--;}
};
int Student::count=0;//在类外用类名限定符初始化;

访问这个静态数据成员的方式:
Student::count;或 Student stu[2]; stu[0].count==stu[1].count;

同全局变量相比,使用静态数据成员的优势。
(1)静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性。
(2)可以实现信息的隐藏,保证了信息的安全性。

总结:对于静态数据成员,在程序中只能提供一个定义,这就意味着静态成员不应该被放在头文件中,
或者是包含inline函数定义的文件中。由于静态成员在类中只有一份定义,在其对象中没有拷贝,因此
静态成员不依托于类对象的存在而存在。因此在没有实体对象的时候,我们访问静态数据成员的时候需
要通过域操作符::来访问。

静态函数成员
静态函数的声明在类中也用关键字static声明。
在上面的成员函数里加上static int GetCount(){return count;}
访问方式:Student::GetCount();
静态函数成员的目的:如果上面那个静态变量不是公有的,那么就不能直接Student::count;这样访问
了,这是不允许的,所以需要留出一个访问出口来访问这个静态变量。
注:静态成员函数可以直接访问该类的静态数据和函数成员。而访问非静态数据成员必须通过参数传递
方式得到对象名,然后通过对象名访问。

总结:静态成员函数和静态成员数据一样,在类对象中只有一份拷贝,对静态函数的调用可以通过类对
象实例,如stu[0].GetCount()。或者像上面那种方式。一般来说,静态成员函数主要用于对静态数据
成员进行维护雨数据共享。

2.常引用
常引用简单来说就是在引用时加一个const修饰符,保证引用访问时不更改该对象。
例如:void Compare(const int& x,const int& y);
常引用一般出现在函数参数表内,用以在函数调用对象的时候保证对象的数据不被更改。一旦更改择会
报错。
例如:
void Compare(const int& x,const int& y);
{
if(x==y)->if(x=y);//有赋值发生x的值改变了,则会报错。
}

3.常成员
类中有时候需要用到某些常量,这些常量如果定义为全局常量,这样的类显然不适合代码移植,所以在
类中定义为类的常成员,就可以很方便的移植了。
class Circlecal
{
private:
double Radius;
const double PI;//常量的定义
public:
Circlecal(double r=0):PI(3.1415)//常量的初始化
{
Radius=r;
}
}
上述是求圆的面积的简洁类定义,PI就是那个常量。
注意常量的初始化只能在初始化列表中给出。

如果像上述则PI在每一个对象都有一份拷贝,造成了数据的冗长,静态常成员数据可以解决这个问题。
如static const double PI;其初始化与静态成员初始化相同,需要在非头文件中初始化。

常成员函数
在普通的函数后面加上const就是一个常成员函数了;
class Circlecal
{
private:
double Radius;
const double PI;//常量的定义
public:
Circlecal(double r=0):PI(3.1415)//常量的初始化
{
Radius=r;
}
double DetR()const;//声明常函数,用于返回圆的半径
}
double Circlecal::GetR()const//定义常函数的时候不可将const省去
{
Radius=3;//错误!不可以改变Radius的值
return Radius;
}

总结:常成员函数不能更新对象的数据成员,也不能够调用任何非常成员函数虽然如此,如果该类中含
有指针,那么在常成员函数中就能修改指针指向的对象,而编译器不会检查到这种错误。

4.常对象
常对象就是对象在生存期内不可更改的对象。
#include <iostream>
#include <cmath>
#include<iomanip>
using namespace std;
class CircleCal
{
private:
double Radius; //定义半径
static const double PI;//静态常成员数据的定义
public:
CircleCal(){};
CircleCal(double);
double Cal(); //声明计算面积函数
double GetR() const;
double GetR();
~CircleCal(){};
};
const double CircleCal::PI=3.1415;//静态常成员数据的初始化
CircleCal::CircleCal(double r):Radius(r){};
double CircleCal::Cal()
{
return pow(Radius,2)*PI;
}
double CircleCal::GetR() const
{
cout<<"const function is loaded"<<endl;
return Radius;
}
double CircleCal::GetR()
{
cout<<"normal function is loaded"<<endl;
return Radius;
}
int main()
{
const CircleCal R1(2.5); //定义CircleCal的常对象R1
// const CircleCal R2; //错误!R2必须被初始化
// cout<<setw(4)<<R1.Cal()<<endl; //错误!R1不能调用非const成员函数
cout<<"the Radius of R is: "
<<setw(4)<<R1.GetR()<<endl;
}
常对象首先需要被初始化,然后使用,在使用过程中,常对象只能调用常成员函数,因为一切调用非常
成员函数都被视为是危险的,即便这个非常成员函数并没有修改成员数据。一般来说,如果需要有常对
象的访问,编写常函数是很重要的。

5.常指针与指针常量
常指针格式:

const 数据类型 *指针名
如const int *p

常指针即:不能通过该指针的间接引用改变所指向的值;但是指针所指变量本身可以改变,指针变量也
可以被不同地址赋值。

指针常量格式:

数据类型 *const 指针名=初始地址
如int *const p=&a

这种指针定义时候就被初始化,以后所存地址都不能改变,但是可以通过间接引用改变所指变量的值

注意:是字符串常量存放在内存中,有自己打固定首地址,也就是说如果把字符串常量的首地址看成是
指针的话,那么该指针既是常指针(值不变)又是指针常量(首地址固定)
另外字符串常量可以又数组或者字符指针方式表示:

用数组表示:
char str_array[]="china";//数组名是指针常量
char *str_ptr="china";//字符指针是常指针

猜你喜欢

转载自www.cnblogs.com/LK-SQ/p/9142766.html