-
构造函数和析构函数
构造函数:创建类的新对象时初始化
析构函数:销毁对象,释放资源
-
访问控制和封装
public/private/protected
struct
关键字,默认成员访问权限是public
。
class
关键字,默认成员访问权限是private
。
封装的好处:
- 被封装的类的具体实现细节可以随意改变,无需调整用户级别的代码。
- 确保用户代码不会无意间破环封装对象的状态。
-
类作用域
在类中定义的数据成员名和成员函数名的作用域为整个类,在类外是未知的,所以在不同类中可以使用相同的类成员名。
访问公有成员函数,必须通过对象。
使用类成员名时,必须根据上下文使用直接成员运算符(.
),间接成员运算符(->
)或作用域解析运算符(::
)。
-
静态成员
静态成员变量:静态成员在类的所有对喜爱嗯中是共享的。如果不存在其他的初始化语句,在创建第一个对象的时候,所有静态成员变量都会被初始化为0。类的定义中不能对静态成员进行初始化,但可以在类的外部通过作用域解析运算符::
初始化。
静态成员函数:与普通成员函数相比,没有this指针。静态成员函数只能访问静态成员数据/其他静态成员函数和类外部的其他函数。
#include <iostream>
class Box {
private:
double length;
double breadth;
double height;
public:
static int ObjectCount;
Box(double l, double b, double h): length(l), breadth(b), height(h) {
std::cout << "Destructor called." << std::endl;
ObjectCount++;
}
};
int Box::ObjectCount = 0;
int main()
{
Box box1(1.0, 1.0, 1.0);
Box box2(2.0, 2.0, 2.0);
std::cout << "ObjectCount: " << Box::ObjectCount << std::endl;
return 0;
}
-
拷贝控制
拷贝构造函数:一个构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数是拷贝构造函数。
class Foo {
public:
Foo();//默认构造函数
Foo(const Foo&);//拷贝构造函数
};
-
重载运算与类型转换
-
虚函数和多态性
virtual
基类声明但是没有定义,留给派生类继承定义。
重载是多态性的一种简单形式。
纯虚函数为各派生类提供一个公共接口。纯虚函数形式:virtual 函数类型 函数名(参数表) = 0
-
抽象基类
#include <iostream>
//含有纯虚函数的基类为抽象基类
//面向抽象类编程(面向一套预先定义好的接口编程)
class Figure
{
public:
virtual void GetArea() = 0;//纯虚函数
};
class Circle : public Figure
{
private:
float m_r;
public:
Circle(float r) : m_r(r) {}
virtual void GetArea()
{
std::cout << "圆的面积为:" << 3.14 * m_r * m_r << std::endl;
}
};
class Triangle : public Figure
{
private:
float m_a;
float m_b;
public:
Triangle(float a, float b) : m_a(a), m_b(b) {}
virtual void GetArea()
{
std::cout << "三角形的面积为:" << m_a * m_b / 2 << std::endl;
}
};
void DisplayArea(Figure * p_figure)
{
p_figure->GetArea();//会发生多态
}
int main()
{
Circle Circle1(2.5);
Triangle Triangle1(1.2, 3.6);
DisplayArea(&Circle1);
DisplayArea(&Triangle1);
return 0;
}
-
类的继承
一个派生类继承了所有的基类方法,但以下情况除外:
- 基类的构造函数/析构函数和拷贝构造函数。
- 基类的重载运算符。
- 基类的友元函数。
-
多重继承和虚继承
#include <iostream>
class Shape {
protected:
int width;
int height;
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
};
class PaintCost {
public:
int getCost(int area) {
return 2 * area;
}
};
class Rectangle: public Shape, public PaintCost {
public:
int getArea() {
return height * width;
}
};
int main()
{
Rectangle rec;
rec.setHeight(2);
rec.setWidth(3);
std::cout << "Total area: " << rec.getArea() << std::endl;
std::cout << "Total cost: " << rec.getCost(rec.getArea()) << std::endl;
return 0;
}
-
类成员指针
#include <iostream>
class Box {
private:
double length;
double breadth;
double height;
public:
static int ObjectCount;
Box(double l, double b, double h): length(l), breadth(b), height(h) {
std::cout << "Constructor called." << std::endl;
ObjectCount++;
}
double volume_of_box();
};
double Box::volume_of_box() {
return length * breadth * height;
}
int Box::ObjectCount = 0;
int main()
{
Box box1(1.0, 1.0, 1.0);
Box box2(2.0, 2.0, 2.0);
Box * ptrBox;
ptrBox = &box1;
std::cout << "Volume of box1: " << ptrBox->volume_of_box() << std::endl;
ptrBox = &box2;
std::cout << "Volume of box2: " << ptrBox->volume_of_box() << std::endl;
std::cout << "ObjectCount: " << Box::ObjectCount << std::endl;
return 0;
}
-
嵌套类和局部类
-
union
//默认情况下联合的成员访问权限是public
union Token {
char cval;
int ival;
double dval;
};
//互斥赋值,token占用的内存大小为最大的数据类型需要的内存,此处为double.
Token token;
token.cval = 'a';
token.ival = 1;
token.dval = 2.0;
-
友元函数和友元类
类外的成员函数访问类的私有成员变量需要使用friend并在类中声明。
类A把类B声明为自己的友元,类B的所有成员函数就可以访问类A对象的私有成员。友元关系在类之间不能传递。