手机网站制作明细报价表,深圳价格实惠的网站建设公司,做押韵句子的网站,做外贸什么网站比较好做c学习之const成员变量与成员函数 常类型是指用类型修饰符const说明的类型#xff0c;常类型的变量或者对象的值是不能被更新的。因此#xff0c;定义或说明常类型时必须初始化。 如果在一个类声明常数据成员#xff0c;那么任何函数中都不能对该成员赋值。构造函数对该成员…c学习之const成员变量与成员函数 常类型是指用类型修饰符const说明的类型常类型的变量或者对象的值是不能被更新的。因此定义或说明常类型时必须初始化。 如果在一个类声明常数据成员那么任何函数中都不能对该成员赋值。构造函数对该成员进行初始化只能通过初始化列表来实现。 #includeiostream 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,raa; a为目标原名称ra为目标引用名。给ra赋值ra1; 等价于 a1; 5声明一个引用不是新定义了一个变量它只表示该引用名是目标变量名的一个别名它本身不是一种数据类型因此引用本身不占存储单元系统也不给引用分配存储单元。故对引用求地址就是对目标变量求地址。ra与a相等。 6不能建立数组的引用。因为数组是一个由若干个元素所组成的集合所以无法建立一个数组的别名。 例如 Point pt1(10,10); Point pt2pt1; 定义了pt2为pt1的引用。通过这样的定义pt1和pt2表示同一对象。 需要特别强调的是引用并不产生对象的副本仅仅是对象的同义词。因此当下面的语句执行后 pt1.offset22 pt1和pt2都具有1212的值。 引用必须在定义时马上被初始化因为它必须是某个东西的同义词。你不能先定义一个引用后才 初始化它。例如下面语句是非法的 Point pt3 pt3pt1 那么既然引用只是某个东西的同义词它有什么用途呢 下面讨论引用的两个主要用途作为函数参数以及从函数中返回左值。 二、引用参数 1、传递可变参数 传统的c中函数在调用时参数是通过值来传递的这就是说函数的参数不具备返回值的能力。 所以在传统的c中如果需要函数的参数具有返回值的能力往往是通过指针来实现的。比如实现 两整数变量值交换的c程序如下 void swapint(int *a,int *b) { int temp; temp*a; *a*b; *btemp; } 使用引用机制后以上程序的c版本为 void swapint(int a,int b) { int temp; tempa; ab; btemp; } 调用该函数的c方法为swapintx,y); c自动把x,y的地址作为参数传递给swapint函数。 2、给函数传递大型对象 当大型对象被传递给函数时使用引用参数可使参数传递效率得到提高因为引用并不产生对象的 副本也就是参数传递时对象无须复制。下面的例子定义了一个有限整数集合的类 const maxCard100; Class Set { int elems[maxCard]; // 集和中的元素maxCard 表示集合中元素个数的最大值。 int card; // 集合中元素的个数。 public: Set () {card0;} //构造函数 friend Set operator * (Set ,Set ) ; //重载运算符号*用于计算集合的交集 用对象作为传值参数 // friend Set operator * (Set ,Set ) 重载运算符号*用于计算集合的交集 用对象的引用作为传值参数 ... } 先考虑集合交集的实现 Set operator *( Set Set1,Set Set2) { Set res; for(int i0;iSet1.card;i) for(int j0;jSet2.card;j) if(Set1.elemsSet2.elems[j]) { res.elems[res.card]Set1.elems; break; } return res; } 由于重载运算符不能对指针单独操作我们必须把运算数声明为 Set 类型而不是 Set * 。 每次使用*做交集运算时整个集合都被复制这样效率很低。我们可以用引用来避免这种情况。 Set operator *( Set Set1,Set Set2) { Set res; for(int i0;iSet1.card;i) for(int j0;jSet2.card;j) if(Set1.elemsSet2.elems[j]) { res.elems[res.card]Set1.elems; break; } return res; } 编辑本段三、引用返回值 如果一个函数返回了引用那么该函数的调用也可以被赋值。这里有一函数它拥有两个引用参数并返回一个双精度数的引用 double max(double d1,double d2) { return d1d2?d1:d2; } 由于max()函数返回一个对双精度数的引用那么我们就可以用max() 来对其中较大的双精度数加1 max(x,y)1.0; 编辑本段四、常引用 常引用声明方式const 类型标识符 引用名目标变量名 用这种方式声明的引用不能通过引用对目标变量的值进行修改,从而使引用的目标成为const达到了引用的安全性。 【例】 int a ; const int raa; ra1; //错误 a1; //正确 这不光是让代码更健壮也有些其它方面的需要。 【例】假设有如下函数声明 string foo( ); void bar(string s); 那么下面的表达式将是非法的 bar(foo( )); bar(hello world); 原因在于foo( )和hello world串都会产生一个临时对象而在C中这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型这是非法的。 引用型参数应该在能被定义为const的情况下尽量定义为const 。 编辑本段五、引用和多态 引用是除指针外另一个可以产生多态效果的手段。这意味着一个基类的引用可以指向它的派生类实例。 【例】 class A; class Bpublic A{……}; B b; A Ref b; // 用派生类对象初始化基类对象的引用 Ref 只能用来访问派生类对象中从基类继承下来的成员是基类引用指向派生类。如果A类中定义有虚函数并且在B类中重写了这个虚函数就可以通过Ref产生多态效果。 分类: C学习(o(∩_∩)o )