C++:常类型Const

简介:


常类型:使用类型修饰符const说明的类型,常类型的变量或对象成员的值在程序运行期间是不可改变的。

3.10.1 常引用

如果在说明引用时用const修饰,则被说明的引用为常引用。如果用常引用做形参,便不会产生对实参
的不希望的更改。常引用的说明形式如下:

const 类型 &引用名;

例如:int a=5;
const int &b=a; 
其中,b是一个常引用,它所引用的对象不允许更改。如果出现:b=12 //则是非法的

在实际应用中,常引用往往用来作形参,这样的参数称为长形参

复制代码
3.39  常引用作函数的参数           
*/
#include<iostream>
using namespace std;
int add(const int &,const int &);  //声明add的形参是常引用 
int main()
{
  int a=20;
  int b=30;
  cout<<a<<"+"<<b<<"="<<add(a,b)<<endl;
  
  a = 15;     //在add函数外,实参是可以改变的 
  b = 50;     //在add函数外,实参是可以改变的
  cout<<a<<"+"<<b<<"="<<add(a,b)<<endl;
  
  return 0; 
}
int add(const int &i,const int &j)   //常引用作函数形参 
{
  //i=i+20;      //不允许改变i的值 
   return i+j; 
} 

/*
程序运行结果: 20+30=50
               15+50=65
               
               
说明:由于add函数两个形参都定义为常引用,所以在函数中不能改变i和j的值,如果改变它们的
      值,编译将会出错,如本程序中执行的函数add加有注释的语句"i=i+20;",将会出现编译
      错误。因此,用常引用作形参,能够避免对是实参的更改,保证了数据的安全性。                
*/
复制代码

3.10.2 常对象 

如果说明对象时用常引用const修饰,则被说明的对象为常对象。常对象的数据成员值在
在对象的整个生存周期内不能被改变。常对象的说明形式如下:

类名 const &对象名[(参数表)]

或 const 类名 &对象名[(参数表)]

在定义对象时必须被初始化,而且不能被更新。

复制代码
3.40   非常对象和常对象的比较  
*/
#include<iostream>
using namespace std;
class Sample{
    public:
        Sample(int m,int n)
        {
          i = m;
          j = n;
        }
        int j;
        void setvalue(int x)
        {
          i = x;
        }
        void show()
        {
          cout<<"i="<<i<<endl;
          cout<<"j="<<j<<endl;
        }
    private:
       int i;
           
};
int main()
{
Sample s(10,20);  //对象s是普通对象,而不是常对象 
s.setvalue(30);
s.j=40;
s.show();  //运行结果是 i=30 j=40 


/*
Sample const s(10,20); //对象s是常对象
s.setvalue(30);  //运行错误,C++不允许间接的更改i的值 
s.j=40;   //运行错误,C++不允许置接的更改j的值 
s.show(); //运行错误,C++不允许常对象调用普通的 
*/

return 0;
}
复制代码

3.10.3 常对象成员

1. 常数据成员
类的数据成员可以是常量或常引用,使用const说明的数据成员称为常数据成员。如果在
一个类中说明了常数据成员,那么构造函数就只能通过成员初始化列表对该数据成员进行
初始化,而其他人任何函都不能对该成员赋值。

复制代码
   例3.41  常数据成员的使用            
*/
#include<iostream>
using namespace std;
class Date{
  public:
    Date(int y,int m,int d);
    void show();
  private:
    const int year;    //常数据成员 
    const int month;   //常数据成员
    const int day;     //常数据成员
};
Date::Date(int y,int m,int d):year(y),month(m),day(d){} //采用成员初始化列表,对数据成员进行初始化 
void Date::show()
{
  cout<<year<<".";
  cout<<month<<".";
  cout<<day<<endl;
} 
int main()
{
 Date date1(2015,5,7);  
 Date date2(2015,5,8); 
 date1.show();
 date2.show();
 return 0;
}

/*
  运行结果为:2015.5.7
                2015.5.8
  
  该程序中定义了如下3个常数据成员:
          const int year;    //常数据成员 
          const int month;   //常数据成员
          const int day;     //常数据成员
          
其中year、month、day是int类型的数据成员。需要注意到是构造函数的格式如下:

     Date::Date(int y,int m,int d):year(y),month(m),day(d){}
     
     其中,冒号后面是一个成员初始化列表,它包含3个初始化项。这是由于year、month、
     和day都是常数据成员,C++规定只能通过构造函数的初始化列表对常数据成员进行初始化。
     在函数体中采用赋值语句对数据成员直接赋初值是非法的。如以下形式的构造函数是错误的:
     
          Date::Date(int y,int m,int d)
          {
            year = y;     //非法 
            month = m;    //非法
            day = d;      //非法
          }
          
   一旦对某对象的常数据成员初始化后,该数据成员的值是不能改变,但不同对象中的该数据成员
   的值可以是不同的(在定义对象时给出) 如: Date date1(2015,5,7);   
                                                Date date2(2015,5,8);
*/
复制代码

2、常成员函数

在类中使用关键字const说明的成员函数为常成员函数,常成员函数的说明格式如下:

类型说明符 函数名(参数表) const;

const是函数类型的一个组成部分,因此在声明函数和定义函数时都要用关键字const,
在调用时不必加const。

复制代码
例3.42 常成员函数的使用             
*/
#include<iostream>
using namespace std;
class Date{
  public:
    Date(int y,int m,int d);
    void show();          //声明普通的成员函数show() 
    void show() const;    //声明常成员函数show() 
  private:
     const int year;      //常数据成员 
     const int month;     //常数据成员
     const int day;         //常数据成员
/*
      int year;   //普通数据成员 
      int month;  //普通数据成员
      int day;    //普通数据成员
*/
};
Date::Date(int y,int m,int d):year(y),month(m),day(d){} //定义构造函数,采用成员初始化列表,
                                                        //对数据成员进行初始化

void Date::show()            //定义普通的成员函数show()
{
  cout<<"Date::show1()"<<endl;
  cout<<year<<".";
  cout<<month<<".";
  cout<<day<<endl;
} 
void Date::show() const       //定义常成员函数show()                                  
{
  cout<<"Date::show2()"<<endl;
  cout<<year<<".";
  cout<<month<<".";
  cout<<day<<endl;
} 
int main()
{
 Date date1(2015,5,7);       //定义普通对象date1
  date1.show();              //调用普通的成员函数show 
   
 const Date date2(2015,5,8); //定义常对象date2 
 date2.show();               //调用常成员函数show
 
 return 0;
}

/*
 程序运行结果如下:
                    Date::show1()
                    2015.4.7 
                    Date::show2()
                    2015.4.8 
 
    本程序中,类Date中说明了两个同名成员函数show,一个是普通成员函数,另一个是常成员函数,
    它们是重载的。可见,关键字const可以被用于区分重载函数。
复制代码

说明:

1、常成员函数可以访问常数据成员,也可以访问普通数据成员。常数据成员可以被常成员函数访问,
也可以被普通成员函数访问。

2、如果将一个对象说明为常对象,则通过该对象只能调用它的常成员函数,而不能调用普通的成员
函数。常成员函数是常对象唯一的的对外接口,这时C++从语法上对常对象的保护。

表3.2 常成员函数和普通成员函数的访问特性比较 
--------------------------------------------------------------------------------------------------------------- 
数据成员 |                         普通成员函数 |                               常成员函数
--------------------------------------------------------------------------------------------------------------- 
普通数据成员                 可以访问,也可以改变值               可以访问,但不可以改变值 

常数据成员                     可以访问,但不可以改变值           可以访问,但不可以改变值

常对象的数据成员         不允许访问和改变值                       可以访问,但不可以改变值

3、常成员函数不能更新对象的数据成员,也不能调用该类中的普通成员函数,这就保证了在常成员
函数中绝对不会更新数据成员的值。 

 

程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!
本文转自当天真遇到现实博客园博客,原文链接:http://www.cnblogs.com/XYQ-208910/p/4912168.html ,如需转载请自行联系原作者
相关文章
|
1月前
|
存储 编译器 程序员
C++类型参数化
【10月更文挑战第1天】在 C++ 中,模板是实现类型参数化的主要工具,用于编写能处理多种数据类型的代码。模板分为函数模板和类模板。函数模板以 `template` 关键字定义,允许使用任意类型参数 `T`,并在调用时自动推导具体类型。类模板则定义泛型类,如动态数组,可在实例化时指定具体类型。模板还支持特化,为特定类型提供定制实现。模板在编译时实例化,需放置在头文件中以确保编译器可见。
32 11
|
2月前
|
安全 程序员 C语言
C++(四)类型强转
本文详细介绍了C++中的四种类型强制转换:`static_cast`、`reinterpret_cast`、`const_cast`和`dynamic_cast`。每种转换都有其特定用途和适用场景,如`static_cast`用于相关类型间的显式转换,`reinterpret_cast`用于低层内存布局操作,`const_cast`用于添加或移除`const`限定符,而`dynamic_cast`则用于运行时的类型检查和转换。通过具体示例展示了如何正确使用这四种转换操作符,帮助开发者更好地理解和掌握C++中的类型转换机制。
|
3月前
|
C++
使用 QML 类型系统注册 C++ 类型
使用 QML 类型系统注册 C++ 类型
58 0
|
4月前
|
编译器 C++ 运维
开发与运维函数问题之函数的返回类型如何解决
开发与运维函数问题之函数的返回类型如何解决
38 6
|
3月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
43 0
|
4月前
|
安全 编译器 C++
C++一分钟之-模板元编程实例:类型 traits
【7月更文挑战第15天】C++的模板元编程利用编译时计算提升性能,类型traits是其中的关键,用于查询和修改类型信息。文章探讨了如何使用和避免过度复杂化、误用模板特化及依赖特定编译器的问题。示例展示了`is_same`类型trait的实现,用于检查类型相等。通过`add_pointer`和`remove_reference`等traits,可以构建更复杂的类型转换逻辑。类型traits增强了代码效率和安全性,是深入C++编程的必备工具。
75 11
|
4月前
|
C++
C++一分钟之-类型别名与using声明
【7月更文挑战第20天】在C++中,类型别名和`using`声明提升代码清晰度与管理。类型别名简化复杂类型,如`using ComplexType = std::vector&lt;std::shared_ptr&lt;int&gt;&gt;;`,需注意命名清晰与适度使用。`using`声明引入命名空间成员,避免`using namespace std;`全局污染,宜局部与具体引入,如`using math::pi;`。恰当应用增强代码质量,规避常见陷阱。
77 5
|
3月前
|
设计模式 安全 IDE
C++从静态类型到单例模式
C++从静态类型到单例模式
38 0
|
4月前
|
编译器 C++
C++从遗忘到入门问题之C++中的浮点数类型问题如何解决
C++从遗忘到入门问题之C++中的浮点数类型问题如何解决
|
4月前
|
C++ 开发者
C++一分钟之-概念(concepts):C++20的类型约束
【7月更文挑战第6天】C++20引入了Concepts,提升模板编程的精确性和可读性。概念允许设定模板参数的编译时约束。常见问题包括过度约束、不完整约束及重载决议复杂性。要避免这些问题,需适度约束、全面覆盖约束条件并理解重载决议。示例展示了如何定义和使用`Incrementable`概念约束函数模板。概念是C++模板编程的强大力量,但也需谨慎使用以优化效率和代码质量。
103 0