Chinaunix首页 | 论坛 | 博客
  • 博客访问: 111209
  • 博文数量: 28
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 202
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-31 21:51
个人简介

諸惡莫做,眾善奉行,自淨其意!

文章分类

全部博文(28)

文章存档

2018年(1)

2017年(3)

2015年(3)

2014年(21)

我的朋友

分类: C/C++

2017-02-13 10:32:44

本博文是根据上的内容归纳汇总而得。



2. 名字空间

名字空间的定义

名字空间除了系统定义的名字空间之外,还可以自己定义,定义名字空间用关键字“namespace”,使用名字空间时用符号“::”指定。




  • 不指定名字空间的变量或函数都是当前名字空间下的变量或函数。
  • 不定义名字空间的情况下,都属于全局名字空间。
  • 同一个名字空间可以定义多次。

    点击(此处)折叠或打开

    1. #include <iostream>
    2. using namespace std;
    3. namespace na
    4. {
    5.     void print(int n) { //与名字空间nb的函数名相同
    6.         cout << "na::print: " << n << endl;
    7.     }
    8. }
    9. namespace nb
    10. {
    11.     void print(int n) { //与名字空间na的函数名相同
    12.         cout << "nb::print: " << n << endl;
    13.     }
    14. }
    15. namespace na // 同一个名字空间可以定义多次
    16. {
    17.     void print2(int a, int b) {
    18.         print(a);
    19.         print(b);
    20.     }
    21. }
    22. int main ( )
    23. {
    24.     na::print(3); // 指定na下的print函数
    25.     nb::print(4); // 指定na下的print函数
    26.     na::print2(5, 6); // 指定na下的print2函数
    27.     return 0;
    28. }
    运行结果:
    na::print: 3
    nb::print: 4
    na::print: 5
    na::print: 6





3. 引用
引用(reference)”与指针象似但不是指针。引用主要有3种用法:
  • 单独使用(一般称为“独立引用”);
  • 作参数使用;
  • 作返回值使用。

独立引用

从功能上来说,引用型变量又可以看做事被引用变量的“别名”,这两个变量只是名称不同,变量的地址是同一个(共用体中的元素也是一样)。使用“引用”的好处主要是可以“逆向引用”。定义独立引用时需要注意以下规则:
  • 引用型变量在定义时必须初始化。
  • 被引用的对象必须已经分配了空间,即不能为空,或空指针。
  • 被引用的对象不能为地址,即指针变量、数组变量等不能被引用。
  • 点击(此处)折叠或打开

    1. #include <iostream>
    2. using namespace std;
    3. int main( )
    4. {
    5.     int a ; // 
    6.     int &b = a; //b和a实际上是同一变量
    7.     b = 100; //b赋值为100,也就是a赋值为100
    8.     int c = b; // c和b的地址不一样
    9.     cout << a << endl;
    10.     //a的地址和b的地址应该是完全一样,但是c的有别于a和b
    11.     cout << &a << endl;
    12.     cout << &b << endl;
    13.     cout << &c << endl;
    14.     /*-------▼下面代码有错,注释后才能运行▼-----------
    15.     int x[] = {12,15,20} ;
    16.     int &y = x; //错误:数组、指针不能被引用
    17.     int x1;
    18.     int &y1; //错误:引用时必须初始化
    19.     y1 = x1;
    20.     -------▲上面代码有错,注释后才能运行▲-----------*/
    21.     return 0;
    22. }



输出结果:
100
0x7fff2b0bb4b4
0x7fff2b0bb4b4
0x7fff2b0bb4b0

函数的参数引用

许多教程在讲解参数引用时都喜欢选择交换两参数内容的swap(int &x, int &y)函数作例子,这的确很容易说明清楚,但并不能说这种用法优于指针作参数。

点击(此处)折叠或打开

  1. #include <iostream>
  2. using namespace std;
  3.                                                 //|右边为指针作参数的代码,仅作比较用。
  4. void swap(int &x, int &y); //|void swap(int *x, int *y);
  5.                                                 //|
  6. int main ( ) //|
  7. { //|
  8.     int i = 12; //|
  9.     int j = 25; //|
  10.     cout << "i=" << i << " j=" << j << endl; //|
  11.                                                 //|
  12.     swap(i, j); //|swap(&i, &j);
  13.     cout << "i=" << i << " j=" << j << endl; //|
  14.                                                 //|
  15.     return 0; //|
  16. } //|
  17.                                                 //|
  18. void swap(int &x, int &y) //|void swap(int *x, int *y)
  19. { //|{
  20.     int t; //| int t;
  21.                                                 //|
  22.     t = x; //| t = *x;
  23.     x = y; //| *x = *y;
  24.     y = t; //| *y = *x;
  25. }

运行结果:
i=12    j=25
i=25    j=12

4. 类和对象

类、实例和对象

类是从C语言中的结构体演变而来,结构体的成员变量也就演化成类的成员变量,这时类只能存放数据。为了在类内部操纵这些数据,增加了成员函数的功能。所谓成员函数就是在类的内部定义,用来操作类的成员变量的函数。随后对成员变量和成员函数附上“私有”、“保护”和“公共”的访问权限,于是“类”便大致成型。事实上,C++中结构体的功能大致和类相当,也有了成员函数。“成员”是成员变量和成员函数的统称。
“类”和结构体一样,是一种自定义的数据类型,但不是基本类型。“实例”是用自己定义的“类”这个数据类型来定义的变量。这些一个一个的实例统称“对象”。另外,“继承”和“派生”是同一件事的不同说法,B类继承了A类,也就是说A类派生了B类。
class 类名 {              //|    class CSample {
访问符:                   //|    public:
    成员变量定义;         //|        int x1;
    成员函数定义;         //|        CSample();
访问符:                   //|    protected:
    成员变量定义;         //|        int a;
    成员函数定义;         //|        float sum(float f1, float f2);
访问符:                   //|    private:
    成员变量定义;         //|        int m;
    成员函数定义;         //|        double sum(double f1, double f2);
......                    //|    ......
}                         //|    }
一般按习惯将private:定义部分放在紧靠类名下面,并且“private:”可以省略。“private:”下面定义的成员全是“私有”的,也就是只能在这个类的成员函数里可以使用,外部(包括派生的子类)不能使用。“public:”下面定义的成员,所有地方都能使用。“protected:”下面定义的成员,在派生的子类中则相当于“public”,其它地方则相当于“private”。

构造函数和析构函数

“构造函数”是类产生实例时被调用,进行初始化设置,是一个特殊的成员函数,函数名与类名相同,没有返回值。一般构造函数定义在“public:”下面,如上述的CSample(),但有时为了阻止多个实例的产生而特意定义在“private:”或“protected:”下面。当初始化时没有什么需要设定时也可以不定义,编译时会自动生成一个默认的构造函数。构造函数的重载使得实例的生成灵活而且方便,默认的构造函数没有参数,且是定义在“public:”下面的。
“析构函数”是类的实例被销毁时调用,进行最后的处理,例如释放动态分配的内存等。一般析构函数定义在“public:”下面,不需要时也可以不定义,编译时会自动生成一个默认的析构函数。析构函数的函数名与类名相同,前面有“~”返回值
下面的例子演示构造函数和析构函数被调用的顺序。

点击(此处)折叠或打开

  1. #include <iostream>
  2. using namespace std;
  3. class CA {
  4.     int a;
  5. public:
  6.     CA(){
  7.         a = 0;
  8.         cout << "构造函数: " << a << endl;
  9.     }
  10.     ~CA(){
  11.         cout << "析构函数: " << a << endl;
  12.     }
  13.     void setA(int x) {
  14.         a = x;
  15.     }
  16.     void print() {
  17.         cout << "print: " << a << endl;
  18.     }
  19. };
  20. int main ( )
  21. {
  22.     CA ca;
  23.     //ca.a = 10; //成员变量a是私有的,不能直接访问
  24.     ca.setA(10);
  25.     ca.print();
  26.     return 0;
  27. }

运行结果:
构造函数:0
print:10
析构函数:10

生成实例的3种方法

了解生成实例的三种方法的细微区别是很重要的:
  • 申明为变量;
  • 从无名对象复制;
  • 申明为指针并动态生成。
注意:指针的成员用“->”,而不用“.”。

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int main ( )
  5. {
  6.     string strA("C语言中文网"); //直接调用构造函数生成实例
  7.     cout << strA << " " << strA.length() << endl;
  8.     string strB; //先调用构造函数生成空字符串实例
  9.     strB = string("C++60分钟入门教程"); //再调用构造函数生成无名实例,然后复制给strB实例,无名实例立即销毁
  10.     cout << strB << " " << strB.length() << endl; //这和上面①的方法的结果相同
  11.     string *strC; //先定义一个指针,尚未分配空间
  12.     //动态调用构造函数生成实例后,再将实例地址赋给指针变量
  13.     strC = new string("");
  14.     cout << *strC << " " << strC->length() << endl;
  15.     delete strC; //千万不要忘记释放
  16.     return 0;
  17. }



运行结果:
C语言中文网    11
C++60分钟入门教程    17
    49

5. 成员函数和运算符的重载

构造函数的重载

构造函数可以重载,使得生成实例时非常方便。构造函数一般要对成员变量赋初值,有两种写法:

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class stuff {
  5.     string name;
  6.     int age;
  7. public:
  8.     stuff() { //这是写法一
  9.         cout << name << "---" << age << endl; // age对应的是
  10.         name = "空";
  11.         age = 0;
  12.         cout << name << "---" << age << endl;
  13.     }
  14.     stuff(string n, int a):name(n),age(a) //这是写法二
  15.     {
  16.         cout << name << "---" << age << endl;
  17.     }
  18.     string getName() {
  19.         return name;
  20.     }
  21.     int getAge() {
  22.         return age;
  23.     }
  24. };
  25. int main ( )
  26. {
  27.     stuff st2;
  28.     stuff st1("C语言中文网", 3);
  29.     return 0;
  30. }
运行结果:
---2817728
空---0
C语言中文网---3
写法一是在构造函数体中赋值,赋值前成员变量已经有了地址空间,尚未有值。写法二是一种特殊方法,是在成员变量分配空间的同时将参数的值赋给成员变量。虽然写法二用的人少,但明显优于写法一。事实上,如果将成员变量的定义改为常量,“const string name;”和“const int age;”,写法一将出错,而写法二仍然正确。

运算符重载

运算符重载对于普通函数和成员函数来说,格式稍有不同。
//单目运算符
成员函数:      返回值类型  operator  运算符  () ;
普通函数:      返回值类型  operator  运算符  (对象的类型) ;

//双目运算符
成员函数:      返回值类型  operator  运算符  (对象的类型) ;
普通函数:      返回值类型  operator  运算符  (对象的类型1, 对象的类型2) ;

//函数调用
成员函数:      返回值类型  operator  (任意的参数列) ;

//数组元素
成员函数:      返回值类型  operator[]  (参数类型) ;

//增1/减1运算符
成员函数:      返回值类型  operator  运算符  (int) ;
普通函数:      返回值类型  operator  运算符  (对象的类型, int) ;

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class stuff {
  5.     string name;
  6.     int age;
  7. public:
  8.     stuff(string n, int a):name(n),age(a)
  9.     {
  10.         cout << name << "---" << age << endl;
  11.     }
  12.     string getName() {
  13.         return name;
  14.     }
  15.     int getAge() {
  16.         return age;
  17.     }
  18.     void operator +(int x); //运算符重载的定义
  19.     void operator +(string s); //运算符重载的定义
  20. };
  21. void stuff::operator +(int x) //运算符重载的实装
  22. {
  23.     age = age + x;
  24. }
  25. void stuff::operator +(string s) //运算符重载的实装
  26. {
  27.     name = name + s;
  28. }
  29. int main ( )
  30. {
  31.     stuff st2("C语言中文网", 3);
  32.     st2 + 2; //+运算
  33.     st2 + ".C++ 60分钟入门教程"; //+运算
  34.     cout << st2.getName() << st2.getAge() << endl;
  35.     return 0;
  36. }
运行结果:
C语言中文网---3
C语言中文网.C++ 60分钟入门教程5




阅读(1466) | 评论(0) | 转发(0) |
0

上一篇:C语言基本入门

下一篇:Python super() 类继承

给主人留下些什么吧!~~