c++学习之const成员变量与成员函数

常类型是指用类型修饰符const说明的类型,常类型的变量或者对象的值是不能被更新的。因此,定义或说明常类型时必须初始化。

如果在一个类声明常数据成员,那么任何函数中都不能对该成员赋值。构造函数对该成员进行初始化,只能通过初始化列表来实现。

#include<iostream>
using namespace std;
class A
{
public:
 A(int i);
 void print();
 const int &r;//常量引用
int c;
private:
 const int a;
 static const int b;//静态数据成员
 
};
const int A::b = 10;//静态常量数据成员在类外初始化
A::A(int i) : a(i), r(c)
{
 
}
void A::print()
{
 cout<< a << ":" << b << ":" << r << endl;
}
int main()
{
 A a1(100), a2(0);
 a1.print();
 a2.print();
//a1.r= 30; 错误,因为r为常量引用。不可通过引用改变目标值.

//用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。 
 return 0;
}

 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。引用的声明方法:类型标识符 &引用名=目标变量名; 说明:(1)&在此不是求地址运算,而是起标识作用。

  (2)类型标识符是指目标变量的类型。

  (3)声明引用时,必须同时对其进行初始化。

  (4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。

  int a,&ra=a;

  a为目标原名称,ra为目标引用名。给ra赋值:ra=1; 等价于 a=1;

  (5)声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。故:对引用求地址,就是对目标变量求地址。&ra与&a相等。

  (6)不能建立数组的引用。因为数组是一个由若干个元素所组成的集合,所以无法建立一个数组的别名。

  例如: Point pt1(10,10);

  Point &pt2=pt1; 定义了pt2为pt1的引用。通过这样的定义,pt1和pt2表示同一对象。

  需要特别强调的是引用并不产生对象的副本,仅仅是对象的同义词。因此,当下面的语句执行后:

  pt1.offset(2,2);

  pt1和pt2都具有(12,12)的值。

  引用必须在定义时马上被初始化,因为它必须是某个东西的同义词。你不能先定义一个引用后才

  初始化它。例如下面语句是非法的:

  Point &pt3;

  pt3=pt1;

  那么既然引用只是某个东西的同义词,它有什么用途呢?

  下面讨论引用的两个主要用途:作为函数参数以及从函数中返回左值。

二、引用参数  1、传递可变参数

  传统的c中,函数在调用时参数是通过值来传递的,这就是说函数的参数不具备返回值的能力。

  所以在传统的c中,如果需要函数的参数具有返回值的能力,往往是通过指针来实现的。比如,实现

  两整数变量值交换的c程序如下:

  void swapint(int *a,int *b)

  {

  int temp;

  temp=*a;

  *a=*b;

  *b=temp;

  }

  使用引用机制后,以上程序的c++版本为:

  void swapint(int &a,int &b)

  {

  int temp;

  temp=a;

  a=b;

  b=temp;

  }

  调用该函数的c++方法为:swapint(x,y); c++自动把x,y的地址作为参数传递给swapint函数。

  2、给函数传递大型对象

  当大型对象被传递给函数时,使用引用参数可使参数传递效率得到提高,因为引用并不产生对象的

  副本,也就是参数传递时,对象无须复制。下面的例子定义了一个有限整数集合的类:

  const maxCard=100;

  Class Set

  {

  int elems[maxCard]; // 集和中的元素,maxCard 表示集合中元素个数的最大值。

  int card; // 集合中元素的个数。

  public:

  Set () {card=0;} //构造函数

  friend Set operator * (Set ,Set ) ; //重载运算符号*,用于计算集合的交集 用对象作为传值参数

  // friend Set operator * (Set & ,Set & ) 重载运算符号*,用于计算集合的交集 用对象的引用作为传值参数

  ...

  }

  先考虑集合交集的实现

  Set operator *( Set Set1,Set Set2)

  {

  Set res;

  for(int i=0;i<Set1.card;++i)

  for(int j=0;j>Set2.card;++j)

  if(Set1.elems==Set2.elems[j])

  {

  res.elems[res.card++]=Set1.elems;

  break;

  }

  return res;

  }

  由于重载运算符不能对指针单独操作,我们必须把运算数声明为 Set 类型而不是 Set * 。

  每次使用*做交集运算时,整个集合都被复制,这样效率很低。我们可以用引用来避免这种情况。

  Set operator *( Set &Set1,Set &Set2)

  { Set res;

  for(int i=0;i<Set1.card;++i)

  for(int j=0;j>Set2.card;++j)

  if(Set1.elems==Set2.elems[j])

  {

  res.elems[res.card++]=Set1.elems;

  break;

  }

  return res;

  }

编辑本段三、引用返回值

  如果一个函数返回了引用,那么该函数的调用也可以被赋值。这里有一函数,它拥有两个引用参数并返回一个双精度数的引用:

  double &max(double &d1,double &d2)

  {

  return d1>d2?d1:d2;

  }

  由于max()函数返回一个对双精度数的引用,那么我们就可以用max() 来对其中较大的双精度数加1:

  max(x,y)+=1.0;

编辑本段四、常引用

  常引用声明方式:const 类型标识符 &引用名=目标变量名;

  用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。

  【例】:

  int a ;

  const int &ra=a;

  ra=1; //错误

  a=1; //正确

  这不光是让代码更健壮,也有些其它方面的需要。

  【例】:假设有如下函数声明:

  string foo( );

  void bar(string & s);

  那么下面的表达式将是非法的:

  bar(foo( ));

  bar("hello world");

  原因在于foo( )和"hello world"串都会产生一个临时对象,而在C++中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。

  引用型参数应该在能被定义为const的情况下,尽量定义为const 。

编辑本段五、引用和多态

  引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。

  【例】:

  class A;

  class B:public A{……};

  B b;

  A &Ref = b; // 用派生类对象初始化基类对象的引用

  Ref 只能用来访问派生类对象中从基类继承下来的成员,是基类引用指向派生类。如果A类中定义有虚函数,并且在B类中重写了这个虚函数,就可以通过Ref产生多态效果。

分类: C++学习(o(∩_∩)o )

c++学习之const成员变量与成员函数相关推荐

  1. C++学习笔记(十)成员变量和成员函数分开存储、this指针、空指针访问成员函数、const修饰成员函数、友元

    1.成员变量和成员函数分开存储 //1.在C++中,类内的成员变量和成员函数分开存储 //2.只有非静态成员变量才属于类的对象上 //空对象占用内存空间为:1 //C++编译器会给每个空对象也分配一个 ...

  2. C++57个入门知识点_17 类的访问权限及C语言模拟类的封装(类的私有权限突破方法:编译期进行权限检查,运行期通过指针修改类的私有成员变量;利用函数指针对结构体中成员变量进行修改;CPU大小尾排列)

    接上篇:C++57个入门知识点_16 类的标准写法(类名.成员变量.成员函数及对象命名规则:成员变量一般为私有,成员函数为公有并暴露给外部使用成员变量:防止类过大,声明写在.h,实现写在.cpp,调用 ...

  3. 成员变量和成员函数分开存储

    首先来说结论: 1.在C++中,类内的成员变量和成员函数分开存储 2.只有非静态成员变量才属于类的对象上 空类(类中上面对象都没没有)占用内存大小为:1 #include <iostream&g ...

  4. Java 多态中成员变量与成员属性的特点【复习】

    package firstchapter;/*** 多态中成员变量与成员属性的特点*/ public class polymorphic {public static void main(String ...

  5. C++成员变量和成员函数分开存储

    C++t成员变量和成员函数分开存储 类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 class Person ...

  6. C++类的成员变量和成员函数的介绍

    类可以看做是一种数据类型,它类似于普通的数据类型,但是又有别于普通的数据类型.类这种数据类型是一个包含成员变量和成员函数的集合. 类的成员变量和普通变量一样,也有数据类型和名称,占用固定长度的内存.但 ...

  7. 类和对象- C++对象模型和this指针- 成员变量和成员函数分开存储

    成员变量和成员函数分开存储 在C++中,类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 空对象占用内存空间 class Person {};void test01() {Pers ...

  8. C++ const成员变量和成员函数

    const成员变量 const 成员变量的用法和普通 const 变量的用法相似,只需要在声明时加上 const 关键字.初始化 const 成员变量只有一种方法,就是通过构造函数的初始化列表. co ...

  9. python中的类的成员变量以及property函数

    1 python类的各种变量 1.1 全局变量 在类外定义的变量. 1.2 类变量 定义在类里面,所有的函数外面的变量.这个变量只有一份,是所有的对象共有的.在类外用"类."来引用 ...

最新文章

  1. 福布斯:14位技术专家预测,未来哪些行业将被AI颠覆?
  2. SAP MM 没有维护MRP 视图的物料可以正常参与采购业务
  3. oracle中聚合比较函数,Oracle聚合函数/分析函数
  4. 五天带你学完《计算机网络》·第二天·数据链路层
  5. FastDFS整合SpringBoot - 实现service
  6. java中用jdom 如何创建xml文档/将数据写入XML中
  7. Leetcode--134. 加油站
  8. 理论基础 —— 线性表 —— 循环链表
  9. python 3解释器_python004 Python3 解释器
  10. 中采购订单批导的bapi_五:认识SAP SD销售模式之第三方销售和单独采购
  11. VSCode中值得推荐的11个摸鱼插件
  12. Laplace锐化算子和LOG算子
  13. sqlite内存模式
  14. 自媒体视频搬运,技术分享给大家!
  15. 出租权不适用于计算机软件,TRIPS协议下我国软件产业知识产权保护问题研究
  16. WPF DEV dxc:ChartControl 柱状图
  17. 赏红叶,是金秋心旷神怡之事
  18. Linux简介(4)--计算机组成与进程及相关命令
  19. android自动修音,唱吧后期处理声音软件下载-唱吧后期修音软件手机版下载 _5577安卓网...
  20. 红领巾小创客机器人活动计划_【动感中队】红领巾小创客之二(2)中队的“我创意,我快乐”活动...

热门文章

  1. 将 Citavi 笔记按需要导出
  2. 光端机常见五大故障问题及解决方法
  3. 光纤收发器一定要成对使用吗?
  4. 【渝粤教育】国家开放大学2018年春季 0025-21T数据结构 参考试题
  5. 【渝粤题库】广东开放大学 建设监理 形成性考核
  6. 亿佰特Lora网关技术为马拉松保驾护航
  7. 【无线电波】蓝牙Bluetooth来源 原理?有无辐射影响健康 是否安全!?
  8. 蓝桥杯基础模块3_2:数码管动态显示
  9. 接受拒绝采样(Acceptance-Rejection Sampling)
  10. 计算机网络的含义是什么意思,互联网的基本含义是什么