目录
1. 类
1.1. 类定义
类定义包含:class关键字;类名称;类主体在一对花括号中,有类成员变量和类成员函数。本质上定义了一个数据蓝图,类对象有成员和操作。
class Box {
public:
double length; // 盒子长
double breadth; // 盒子宽
double height; // 盒子高
};
静态建立:建立一个类对象,编译器为对象在栈中分配内存。
动态建立:Box *b = new Box(); 动态建立一个对象,编译器为对象在堆空间分配内存。
组合类:一个类的数据成员是另一个类的对象。创建时既要对基类成员初始化,又要对内嵌对象初始化。
1.2. 对象创建访问
Box Box1; // 声明 Box1
Box Box2; // 声明 Box2
// 访问用.
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
1.3. 类成员函数
类成员函数定义
class Box {
public:
double length; // 盒子长
double breadth; // 盒子宽
double height; // 盒子高
double getVolume(void) { // 类成员函数内部定义:求盒子体积
return length * breadth * height;
}
};
// 类成员函数外部定义:求盒子体积
double Box::getVolume(void) {
return length * breadth * height;
}
类成员函数调用
Box myBox; // 创建一个对象
myBox.getVolume();
1.3 类访问修饰符
public:公有成员;类外部可以访问;
protected:受保护成员;类外部不可访问,类、派生类和友元函数可以访问;
private:私有成员;类外部不可访问,只有类和友元函数可以访问。
1.4. 类构造函数和析构函数
构造函数:创建类的新对象时候,初始化成员。
#include <iostream>
using namespace std;
class Line {
public:
void setLength(double len);
double getLength(void);
Line(double len); // 这是构造函数
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line(double len) {
cout << "Object is being created, length = " << len << endl;
length = len;
}
void Line::setLength(double len) {
length = len;
}
double Line::getLength(void) {
return length;
}
列表初始化:
C::C( double a, double b, double c): X(a), Y(b), Z(c) {
....
}
析构函数:删除创建对象,回收资源。析构函数不可抛出异常,以免控制权转出构造函数外造成内存泄漏。类有成员类对象,后者有析构函数,会以其声明顺序的相反顺序被调用。成员类对象有vptr,有任何上一层非虚基类有析构函数,以声明顺序被调用。
#include <iostream>
using namespace std;
class Line {
public:
void setLength(double len);
double getLength(void);
Line(); // 构造函数声明
~Line();// 析构函数声明
private:
double length;
};
// 成员函数定义,包括构造函数
Line::Line(void) {
cout << "Object is being created" << endl;
}
Line::~Line(void) {
cout << "Object is being deleted" << endl;
}
void Line::setLength(double len) {
length = len;
}
double Line::getLength(void) {
return length;
}
1.5. 拷贝构造函数
1.6. 友元
友元函数、友元类:定义在类外部,有权访问类的所有private和protected成员。
代码示例:定义类Box和友元函数
class Box {
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};
void printWidth(Box box) {
/* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
cout << "Width of box : " << box.width <<endl;
}
1.7. 内联函数
由inline定义,编译时该函数的代码副本会被放置在被调用的地方,函数体较小时,效率较高。滥用可能导致程序变慢。
#include <iostream>
using namespace std;
inline int Max(int x, int y) {
return (x > y)? x : y;
}
int main() {
cout << "Max (20,10): " << Max(20,10) << endl;
return 0;
}
1.8. this指针
作用:指向当前对象实例;隐藏指针。
代码示例:
#include <iostream>
class MyClass {
private:
int value;
public:
void setValue(int value) {
this->value = value;
}
void printValue() {
std::cout << "Value: " << this->value << std::endl;
}
};
int main() {
MyClass obj;
obj.setValue(42);
obj.printValue();
return 0;
}
1.9. 指向类的指针
指向类的指针访问->。
代码示例:
#include <iostream>
using namespace std;
class Box {
public:
Box(double l=2.0, double b=2.0, double h=2.0) {
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
}
double Volume() {
return length * breadth * height;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
int main(void) {
Box Box1(3.3, 1.2, 1.5); // Declare box1
Box *ptrBox; // Declare pointer to a class.
ptrBox = &Box1;
cout << "Volume of Box1: " << ptrBox->Volume() << endl;
return 0;
}
1.10. 静态成员
static修饰的成员,类的所有对象共享,在类外初始化。
类的成员变量代码示例:
#include <iostream>
using namespace std;
class Box {
public:
static int objectCount;
Box(double l=2.0, double b=2.0, double h=2.0) {
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
objectCount++;
}
double Volume() {
return length * breadth * height;
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
// 初始化类 Box 的静态成员
int Box::objectCount = 0;
int main(void) {
Box Box1(3.3, 1.2, 1.5); // 声明 box1
Box Box2(8.5, 6.0, 2.0); // 声明 box2
// 输出对象的总数
cout << "Total objects: " << Box::objectCount << endl;
return 0;
}
类的成员函数代码示例:
#include <iostream>
using namespace std;
class Box {
public:
static int objectCount;
Box(double l=2.0, double b=2.0, double h=2.0) {
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
objectCount++;
}
double Volume() {
return length * breadth * height;
}
static int getCount() {
return objectCount;
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
// 初始化类 Box 的静态成员
int Box::objectCount = 0;
int main(void) {
cout << "Inital Stage Count: " << Box::getCount() << endl;
Box Box1(3.3, 1.2, 1.5); // 声明 box1
Box Box2(8.5, 6.0, 2.0); // 声明 box2
cout << "Final Stage Count: " << Box::getCount() << endl;
return 0;
}
2. 面向对象
2.1. 继承
继承定义:依据原始定义类来定义另一个新建类,这样代码可复用,效率高。原始定义类为基类,新建类为派生类。派生类继承了基类所有方法,除构造函数、析构函数、拷贝构造函数、重载运算符、友元函数。一个派生类可以有多个基类。
继承类型:public,protected(基类public和protected成员变为派生类protected成员),private(基类public和protected成员变为派生类private成员)。
代码示例:
// 基类
class Animal {
eat();
sleep();
};
//派生类
class Dog : public Animal {
bark();
};
继承访问控制
访问 | public | protected | private |
同一个类 | yes | yes | yes |
派生类 | yes | yes | no |
外部类 | yes | no | no |
2.2. 多态
多态定义:顾名思义,多种形态。
多态代码示例:
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape(int a=0, int b=0) {
width = a;
height = b;
}
int area() {
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle(int a=0, int b=0):Shape(a, b) { }
int area () {
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle(int a=0, int b=0):Shape(a, b) { }
int area () {
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// 程序的主函数
int main() {
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// 存储矩形的地址
shape = &rec;
// 矩形求面积
shape->area();
// 存储三角形的地址
shape = &tri;
// 三角形求面积函数
shape->area();
return 0;
}
虚函数:基类中用virtual声明,派生类中重新定义基类虚函数时候为动态链接或后期绑定。
纯虚函数:基类中定义的虚函数,未给出有意义的实现,派生类中会重新定义。
哪些函数不是虚函数?构造函数:续表指针在构造函数中初始化;内联函数:虚函数需要运行期间确定类型,内联函数编译时替换;静态函数:不属于对象,属于类,设置没有意义;友元函数:不属于类成员函数,不能被继承;
2.3. 重载运算符
代码示例:
#include <iostream>
using namespace std;
class Box {
public:
double getVolume(void) {
return length * breadth * height;
}
void setLength(double len) {
length = len;
}
void setBreadth(double bre) {
breadth = bre;
}
void setHeight(double hei) {
height = hei;
}
// 重载 + 运算符
Box operator+(const Box& b) {
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
// 程序的主函数
int main( )
{
Box Box1;
Box Box2;
Box Box3;
double volume = 0.0; // 把体积存储在该变量中
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
Box3 = Box1 + Box2;
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume <<endl;
return 0;
}
2.4. 重载函数
代码示例:
#include <iostream>
using namespace std;
class printData {
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
int main(void)
{
printData pd;
// 输出整数
pd.print(5);
// 输出浮点数
pd.print(500.263);
// 输出字符串
char c[] = "Hello C++";
pd.print(c);
return 0;
}