Chinaunix首页 | 论坛 | 博客
  • 博客访问: 25329
  • 博文数量: 33
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2015-10-06 22:37
文章分类
文章存档

2015年(33)

我的朋友
最近访客

分类: C/C++

2015-10-11 21:28:03

     C++设计的核心在于引入了类的概念,为程序猿们提供了自定义数据类型的空间,借助类的实现,奠定了面向对象编程的基石,使得程序的编写、扩展、维护都更加方便。今天就来简单总结下这部分内容,时间紧忙里偷闲看的,拣自己感觉重要的来写吧。

一、类的定义和声明
     类背后蕴含的基本思想是数据的抽象与封装。数据抽象,将接口/方法的使用和实现分离开来,使得设计者和使用者各司其职,设计者专注于类的设计与实现,使用者则只需要关心如何使用类提供的接口。数据封装,将数据成员利用private标号保护起来,外部的函数方法不可见,有效地保护了类自身的数据。数据抽象和封装密切不可分,某种意义上,正是由了数据的抽象提供的公共接口才使得数据可以被封装在类内。二者结合的好处就是:数据成员封装有效避免了无意的、可能破坏对象状态的用户级错误(用户无法直接接触类的核心数据);程序的修改、扩展以及维护都只需要关注类的内部,极大地减少了后期需要的成本。
     这部分另一个比较重要的是类定义与类声明的区别。如果从编译器的角度来看,类声明是告诉这个类型不是“黑户”,类定义则是正式为合法户口安排“住”的空间。因此,经过声明的类只是不完全体,只有定义之后才真正可用。定义对象时必须在进行了类的定义之后(说明了类的数据成员和成员函数)。一般来说,只有在类定义之后,数据成员才能被声明为该类型,因此,类中是不能含有自身类型的数据成员的;但是对于引用和指针而言,她们只需要声明就可以了,而类名已出现恰恰就可以认为是类的声明了:
class  A
{
     ... ...
}
class B
{
     A  class-obj-A;                                           //A类型的数据成员
     A  *next;                                                    //引用和指针
     A  &class-obj-B;
}


二、类作用域
     C++中的变量可能出现在成员函数中、类中以及全局中,因此当遇到一个变量进行名称解析时,C++遵循以下规则:
1. 检查成员函数局部作用域中的声明
2. 如果在成员函数中找不到,则检查对所有类成员的声明
3. 如果在类中仍旧找不到该名字的声明,则检查在此成员函数定义之前的作用域中出现的声明
比如下面的例子:

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <cstdlib>

  3. using namespace std;

  4. string str = "Global";

  5. class Scope
  6. {
  7.     public:
  8.       Scope():str("ClassMem"){};
  9.       void print(string str)
  10.       {
  11.       cout << "str in the function is "<<str<<endl;
  12.       }
  13.       void cout_str()
  14.       {
  15.            cout << "str in the Class-Private is "<<str<<endl;
  16.        }
  17.     private:
  18.       string str;
  19.       };
  20.       
  21. int main()
  22. {
  23.     cout << "This is a test for Class Scope..."<<endl;
  24.     Scope scp;
  25.     scp.print("I'm in the function");
  26.     scp.cout_str();
  27.     
  28.     system("pause");
  29.     return 0;
  30.     
  31.     
  32. }
运行后结果如下:可以看到成员函数中的变量会屏蔽掉类中的变量成员



三、构造函数
     其实对于构造函数有很多值得注意的,比如构造函数的原型(不能有返回值,名称与类名一致),比如构造函数利用形参列表进行重载,利用初始化列表进行类成员的初始化等等。这些都是最基本也是最重要的东西,今天来说说别的。自己看C++ Primer就是一本入门书,但是讲的非常详细。这部分需要特别留意默认构造函数。
     我们知道,当我们没有定义构造函数的时候,C++会使用默认构造函数,默认构造函数会为数据成员赋予初始值,对于类类型来说,直接调用其默认构造函数;内置和复合类型的成员,比如指针和数组,只对定义再全局作用域中的对象才初始化,当对象定义在局部作用域时,内置或复合类型的成员不会进行初始化。所以这就提醒我们:在构造函数中利用初始化列表初始化内置或复合类型的数据成员。


四、友元
     我们经常需要访问一个全局的变量,比如某个计数器,或者某个特定的数值等,如果使用全局变量,就会破坏对用户级错误的保护。但是我们可以使用友元类型声明需要全局访问的函数和类。友元可以修饰在类上,则友元类的函数可以方位自身的private成员;也可以修饰在其他类的某个成员函数,则有同样的效果。这里需要注意是,当生命友元类时,应当首先声明该类,然后才能将该类声明为新一个类友元类。


五、static成员
     static成员很重要,最需要注意的是static成员属于类而更不属于类的对象。因此当然不能对其使用this指针,也不能声明为const函数(没有对应的操作对象)。另外一个需要注意的是,static变量只能在类定义体内声明,在类定义体外定义,并且在体外定义时不能再重复声明static属性(当然也有const static的例外)。
阅读(279) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~