既要使数据能在一定范围内共享,又要保证它不被任意修改,可使用
const
。
·
用
const
修饰的声明数据成员称为常数据成员
·
用
const
修饰的声明成员函数称为常成员函数
·
用
const
修饰的定义对象称为常对象
变量或对象被
const
修饰后其值不能被更新。因此被
const
修饰的变量或对象必须要进行初始化。
(一)用
const
修饰的声明数据成员称为常数据成员
有两种声明形式:
const int cctwl;
int const cctwl;
不能省略数据类型,可以添加
public private
等访问控制符。
说明:
1.
任何函数都不能对常数据成员赋值。
2.
构造函数对常数据成员进行初始化时只能通过初始化列表进行。(只有此一种方法)
3.
常数据成员在初始化时必须赋值或称其必须初始化
.
4.
如果类有多个默认构造函数必须都初始化常数据成员。
通过下面例子来理解常数据成员以上
4
点。
这样也可以给常数据成员
num
赋值啊,而且可以不同的对象赋不同的值。
#include<iostream>
using namespace std;
class Student
{
private:
const int num;
int score;
public:
Student(int a, int b):num(a)
{
score = b;
}
void display();
};
void Student::display()
{
cout << num << endl << score << endl;
cout << "sizeof(int)" << sizeof(int) << endl;
cout << "sizeof(Student)" << sizeof(Student) << endl;
}
int main()
{
Student stu(5,8);
stu.display();
return 0 ;
}
运行结果如图:
A
、请指出下面程序的错误
class A
{
private:
int w, h;
const int ci = 5; //错误一
public:
};
void main()
{
A a; //错误二
cout << "sss";
return 0;
}
错误二:没有合适的默认构造函数可用。因为有常量
ci
没有初始化,必须初始化所有常数据成员。
更正后结果如下:
class A
{
private:
int w, h;
const int ci;
public:
const int ci_2; //可以是公有私有访问权限
A():ci(1),ci_2(2){} //通过构造函数初始化列表初始化常数据成员
};
B
、多个构造函数下的常数据成员
请指出下面程序的错误:
class A
{
private:
int w, h;
const int ci;
public:
const int ci_2;
A():ci(1),ci_2(2){}
A(int x, int y) //错误一
{
w = x;
h = y;
}
};
void main()
{
A a;
A b(3,5);
cout << "sss";
return 0;
}
错误一:每个构造函数都要初始化常数据成员,应改为
A(int x, int y):ci(7),ci_2(8)
{
w = x;
h = y;
}
(二)用
const
修饰的声明声明成员函数称为常成员函数
声明:
<
类型标志符
>
函数名(参数表)
const
;
说明:
1. const
是函数类型的一部分,在实现部分也要带该关键字。
2. const
关键字可以用于对重载函数的区分。
3.
常成员函数不能用来更新类的成员变量,也不能调用类中未用const修饰的成员函数,只能调用常成员函数。即常成员函数不能更改类中的成员状态,这与const语义相符。
A
、通过例子来理解
const
是函数类型的一部分,在实现部分也要带该关键字。
class A
{
private:
int w,h;
public:
int getValue() const;
int getValue();
A(int x,int y)
{
w=x;
h=y;
}
A(){}
};
int A::getValue() const //实现部分也带该关键字
{
return w*h;
}
void main()
{
A const a(3,4);
A c(2,6);
cout << a.getvalue()<<c.getValue() <<"test";
return 0;
}
B
、通过例子来理解
const
关键字的重载
class A
{
private:
int w,h;
public:
int getValue() const;
int getValue();
A(int x,int y)
{
w=x;
h=y;
}
A(){}
};
int A::getValue() const //实现部分也带该关键字
{
return w*h;
}
int A::getValue()
{
return w+h;
}
int main()
{
A const a(3,4);
A c(2,6);
cout << a.getvalue()<< c.getValue() << "test";
return 0;
}
C
、通过例子来理解常成员函数不能更新任何数据成员
class A
{
private:
int w,h;
public:
int getValue() const;
int getValue();
A(int x,int y)
{
w=x;
h=y;
}
A(){}
};
int A::getValue() const //实现部分也带该关键字
{
// w = 10; h = 10; // 错误,常成员函数不能更新非常数据成员
return w*h;
}
int A::getValue()
{
w = 10; h = 10;
return w+h;
}
int main()
{
A const a(3,4);
A c(2,6);
cout << a.getValue() << endl << c.getValue() << endl << "test";
return 0;
}
D
、通过例子来理解
1
、常成员函数可以被其他成员函数调用。
2
、但是不能调用其他非常成员函数。
3
、只可以调用其他常成员函数。
class A
{
private:
int w,h;
public:
int getValue() const
{
// return w*h + getValue2(); // 错误,常成员函数不能调用非常成员函数
return w*h;
}
int getValue2()
{
return w+h+getValue();
}
A(int x,int y)
{
w=x;
h=y;
}
A(){}
};
int main()
{
A const a(3,4);
A c(2,6);
cout << a.getValue() << endl << c.getValue2() << endl << "test";
return 0;
}
(三)用
const
修饰的定义对象称为常对象
常对象是指对象的数据成员的值在对象被调用时不能被改变。常对象必须进行初始化,且不能被更新。不能通过常对象调用普通成员函数,但是可以通过普通对象调用常成员函数。常对象只能调用常成员函数。
常对象的声明如下:
const <
类名
> <
对象名
>
<
类名
> const <
对象名
>
两种声明完全一样没有任何区别。
1
、通过下面例子来理解常对象:
A
、请指出下面程序的错误
class A
{
private:
int w,h;
public:
int getArea() const
{
return w*h;
}
int getW()
{
return w;
}
void setWH(int x,int y)
{
w = x;
h = y;
}
A(int x,int y)
{
w=x;
h=y;
}
A(){}
};
int main()
{
A a; //普通对象不初始化不会报错
a.setWH(3,9);
A const b(3,6);//常对象必须声明的同时初始化
// b.setWH(3,7); //错误:因为b是常对象,不能调用非常成员函数。
cout << a.getArea() << endl << b.getArea() << endl << "test";
return 0;
}
PS:
既要使数据能在一定范围内共享,又要保证它不被任意修改,这时可以使用
const
。对于
const int *pa
,指的是不能通过改变
*pa
的值来改变
pa
指向的变量的值,但可以通过改变
pa
指向的变量的值来改变
*pa
的值。
设置为常引用,还是可以改变实际的值。(但不可用*pa或b来改变a的值)
指向对象的常指针,其指向始终不变。
指向常变量的指针变量:
const
类型名
*
指针变量名;(把变量换成对象,即指向常对象的指针变量同下)
1
、如果一个变量已被声明为常变量,只能用指向常变量的指针变量指向它,而不能用一般的(指向非
const
型变量的)指针变量指向它。
2
、指向常变量的指针变量除了可以指向常变量外,还可以指向未被声明为
const
的变量。此时不能通过此指针变量改变该变量的值
3
、如果函数的形参是指向非
const
型变量的指针,实参只能用指向非
const
变量的指针,而不能用指向
const
变量的指针
在
C++
面向对象程序设计中,经常用常指针和常引用作函数参数。这样既能保证数据安全,使数据不能被随意修改,在调用函数时又不必建立实参的拷贝。用常指针和常引用作函数参数,可以提高程序运行效率。