基类派生类
非常感谢我的队友大爹给我的复习资料
面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。
当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。
继承代表了 is a 关系。例如,哺乳动物是动物,狗是哺乳动物,因此,狗是动物,等等。
一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式如下:
1class derived-class: access-specifier base-class
其中,访问修饰符 access-specifier 是 public、protected 或 private 其中的一个,base-class 是之前定义过的某个类的名称。如果未使用访问修饰符 access-specifier,则默认为 private。
示例
1234567891011121 ...
运算符重载
非常感激我队友大爹给我的复习资料
您可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
1Box operator+(const Box&);
声明加法运算符用于把两个 Box 对象相加,返回最终的 Box 对象。大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数,如下所示:
1Box operator+(const Box&, const Box&);
示例
1234567891011121314151617181920212223242526272829303132333435363738394041424344#include <iostream>using namespace std;class Box {public: double getV ...
函数重载
重载运算符和重载函数
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。
重载函数
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。
下面的实例中,同名函数 print() 被用于输出不同的数据类型:
123456789101112131415161718192021222324252627282930313233#include <iostream>using namespace std;class printData { public: void print(int i) { cout < ...
内嵌对象
非常感激我队友大爹给我的复习资料
类的成员变量为用户自定义的类型时,这些成员变量称为内嵌对象。对象嵌入称做"has-a"关系,就本例来说” World has a Master"。
示例
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051/*类的成员变量为用户自定义的类型时,这些成员变量称为内嵌对象。对象嵌入称做"has-a"关系,就本例来说” World has a Master"。*/#include <iostream>using namespace std;class Master{ private: int _identifier; public: Master(int id) : _identifier(id){ cout << "Master for " ...
类访问修饰符和指向类的指针
类访问修饰符
数据封装是面向对象编程的一个重要特点,它防止函数直接访问类类型的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的。关键字 public、private、protected 称为访问修饰符。
public
公有成员在程序中类的外部是可访问的。您可以不使用任何成员函数来设置和获取公有变量的值
private
私有成员变量或函数在类的外部是不可访问的,甚至是不可查看的。只有类和友元函数可以访问私有成员。
默认情况下,类的所有成员都是私有的。
procted
protected(受保护)成员变量或函数与私有成员十分相似,但有一点不同,protected(受保护)成员在派生类(即子类)中是可访问的。
继承中的特点
有 public, protected, private 三种继承方式,它们相应地改变了基类成员的访问属性。
1.public 继承:基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:public, protected, private
2 ...
拷贝构造函数
非常感激我队友大爹给我的复习资料
拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。
如果在类中没有定义构造拷贝函数,编译器会自行定义一个。如果类带有指针变量,并有动态分配内存,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下:
123classname (const classname &obj) { // 构造函数的主体}
具体示例
1234567891011121314151617181920212223242526272829303132333435363738394041#include <iostream>using namespace std;class Example{ private: int a; public: // 构造函数 Example(int b) { a = b; } // 拷贝构造函数 Example(const Example& ...
友元函数
定义
类的友元函数定义在类外部,但有权访问类的所有private成员和protected成员。
尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。
友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类以及所有成员都是友元。
如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字friend,如下所示。
12345678class Box { double width;public: double length; friend void printWidth( Box box ); friend class ClassTwo; void setWidth( double wid );};
示例
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647#include <iostream>using namespace std;class Box ...
static用法
非常感激我队友大爹给我的复习资料
静态局部变量
在局部变量前, 加上关键字static,该变量就被定义成一个静态局部变量。
通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存, 但随着程序退出函数体,系统就会收回栈内存, 局部变量也相应失效,但有时我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序维护带来不便。
静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用直到下次重新赋值。
1234567891011121314151617void fn(){ static int n = 10; cout << n << endl; n++;}fn();fn();fn();/*========输出结果:101112========*/
特点
静态局部变量具有以下特点:
该变量在全局数据区分配内存
静态局部变量在程序执行到该对象的声明处时被首次初始化 ...
析构函数
非常感激我队友大爹给我的复习资料
什么是析构函数
类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
一个类内可以有多个构造函数,可以是一般类型的,也可以是带参数的,相当于重载构造函数。但是析构函数只能有一个。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀。
定义方式:~类名(无参数){}
示例代码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354#include <iostream>using namespace std;class Matrix{ private: int row; int col; public: Matrix(int r, int c); Matri ...
类初始化常量成员和引用成员
非常感激我队友大爹给我的复习资料
凡是有引用类型的成员变量或者常量类型的变量的类,不能有缺省构造函数。
默认构造函数没有对引用成员提供默认的初始化机制,也因此造成引用未初始化的编译错误。
并且必须使用初始化列表进行初始化const对象、引用对象。
直接赋值报错
1234567891011121314151617181920212223242526272829303132333435363738#include <iostream>using namespace std;class A{ private: int & a; int _b; public: A(int target, int b) : a(target), _b(b){ cout << "Constructor Function" << endl; } // A(int target, int b) { ...