C++ primer学习12.20

来源:互联网 发布:arp s绑定mac 编辑:程序博客网 时间:2024/06/06 01:52

一、类

1.1构造函数

没有返回类型,形参数无要求,以分号结尾。

用class关键字定义的类,最开始没有写访问标号的成员是私有的,而struct则公有。

class Sales_item{
int a;//私有public:Sales_item():units_sold(0),revenue(0){}//不加分号,若不定义,只声明,则加。private:string isbn;unsigned units_sold;double revenue;};
有时需要构造函数初始化列表,如:


class ConstRef{public:ConstRef(int ii);private:int i;const int ci;int &ri;};ConstRef::ConstRef(int ii){i=ii;ci=ii;//错误,不能给const对象赋值ri=i;//错误,ri引用对象没有初始化,不能赋值}

这是错误的程序


改成这样,加上初始化列表:

ConstRef::ConstRef(int ii):i(ii),ci(i),ri(ii){}

记住,const或引用类型数据成员初始化的唯一机会在构造函数初始化列表中。


成员初始化顺序:成员定义的顺序,而不是初始化列表中顺序。

如:

class X{int i;int j;public:X(int val):j(val),i(val){}//i先初始化。};

1.2static类成员

静态成员的提出是为了解决数据共享的问题。实现共享有许多方法,如:设置全局性的变量或对象是一种方法。但是,全局变量或对象是有局限性的。这一章里,我们主要讲述类的静态成员来实现数据的共享。
使用static成员而不是全局对象有三个优点:
1 static成员的名字在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突;
2 可以实现封装,static成员可以是私有的,而全局对象则不可以;
3 static成员 是与特定类关联的,并不与类的对象关联。

  静态数据成员

  在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。

  使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。

  静态数据成员的使用方法和注意事项如下:

  1、静态数据成员在定义或说明时前面加关键字static。

  2、静态成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式如下:

    <数据类型><类名>::<静态数据成员名>=<值>

  这表明:

      (1) 初始化只能在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆,且只能初始化一次;

  (2) 初始化时不加该成员的访问权限控制符private,public等。

  (3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。
       (4) static数据成员的类型可以是所属类的类型,还可以用作所属类的成员函数的默认实参;而非static数据成员可以被限定为所属类对象的引用或者指针,且不能用作默认实参。

  3、静态数据成员是静态存储的,它是静态生存期,必须对它进行初始化。

  4、引用静态数据成员时,采用如下格式:

   <类名>::<静态成员名>

  如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员。

  下面举一例子,说明静态数据成员的应用:

#include 
class Myclass
{
public:
Myclass(int a, int b, int c);
void GetNumber();
void GetSum();
private:
int A, B, C;
static int Sum;
};

int Myclass::Sum = 0;

Myclass::Myclass(int a, int b, int c)
{
A = a;
B = b;
C = c;
Sum += A+B+C;
}

void Myclass::GetNumber()
{
cout<<"Number="<<a<<","<<b<<","<<c<<endl;
}

void Myclass::GetSum()
{
cout<<"Sum="< }

void main()
{
Myclass M(3, 7, 10),N(14, 9, 11);
M.GetNumber();
N.GetNumber();
M.GetSum();
N.GetSum();
}
</a<<","<<b<<","<<c<<endl;
  从输出结果可以看到Sum的值对M对象和对N对象都是相等的。这是因为在初始化M对象时,将M对象的三个int型数据成员的值求和后赋给了Sum,于是Sum保存了该值。在初始化N对象时,对将N对象的三个int型数据成员的值求和后又加到Sum已有的值上,于是Sum将保存另后的值。所以,不论是通过对象M还是通过对象N来引用的值都是一样的,即为54。
特殊的const static数据成员:
只要初始化式是一个常量表达式,整型const static数据成员就可以在类的定义体内进行初始化,C++primer注释说该数据成员仍必须在类外进行定义,而不必指定初始值;但实际在VS2008中运行时是不必要在类定义体外进行定义的。
class account
{
pubilc:
    static double rate();
//........
private:
    static const int period=30;
    //........
};
const int account::period;  //定义可要可不要,但不必再次指定初始值
静态成员函数:
静态成员函数可以类内或类外定义,但必须在类内声明;
static成员函数没有this指针,所以不能直接引用非static数据成员;
static成员不是任何对象的组成,所以static成员函数不能被声明为const,因为const只限定该类的对象;
static成员函数不能同时被声明为虚函数。


术语:

不完全类型:已经声明但未定义的类型,不可以使用不完全类型来定义变量或类成员。但是定义指向不完全类型的引用和指针是可以的。

原创粉丝点击