C++ 中的类
1.定义一个类
C++中用class关键字定义一个类。类的成员默认访问权限是私有的,即只能在类内使用。C++提供了三个访问控制符:
- public:成员在整个程序内都可以被访问。puclic成员定义类的接口。
- private: 成员只能被类的成员函数访问,不能被使用该类的代码访问,实现类的封装性。
- protected: 成员可以被类的成员函数访问,也可以被它派生类访问。
一个类中可以出现多个访问控制符,每个访问控制符也可以出现多次,其有效范围直到下一个访问控制符。
1.1 类定义示例
//class 关键字加 类名
class A{
public: //公有成员访问修饰符
int a; //定义公有成员变量
void printA() //定义公有成员函数
{
cout << "a=" << a << endl;
};
A(); //定义构造函数
A(int a); //定义带参数构造函数
~A(); //定义析构函数
private: //私有成员访修饰符
int b; //定义私有成员变量
void printB(){ //定义私有成员函数
cout << "b=" << b << endl;
};
protected: //保护成员修饰符
int c; //定义保护成员
void printC(){ //定义保护成员函数
cout << "c=" << c << endl;
};
public: //再次声明公共成员。
int d;
void printD(){
cout << "d=" << d << endl;
}
}
1.2 类的使用示例
#include <iostream>
using namespace std;
int main(){
//实例化类的对象
A a();
//修改公共成员的值。
a.a = 10;
a.d = 15;
//调用类的公共接口。
a.printA();
a.printD();
//私有成员与保护成员不可被访问。
//a.b a.printB() a.c a.printC();
}
2. 类的构造函数
构造函数是没有返回值与类同名的函数。
几种特殊的形式称为默认构造函数、拷贝构造函数、移动构造函数、委托构造函数。
构造函数的作用是初始化类的数据成员。无论何时,只要类的对象被创建,就会执行构造函数。
2.1 构造函数定义示例
class A{
private:
int a;
public:
//定义默认构造函数
A();
//带参构造函数
A(int a);
//委托构造函数
//A():A(0);
//拷贝构造函数
A(const A &a);
//移动构造函数
A(A &&) : noexcept;
}
2.2 默认构造函数
class A{
//默认构造函数
A();
}
与类名相同,并且没有参数的构造函数被称为默认构造函数,当我们定义类时,如果没有定义构造函数,编译器会为我们自动定义一个默认构造函数。
2.3 拷贝构造函数
class A{
//拷贝构造函数
A(const A &a);
}
基础数据类型的赋值比较简单,对象之间的赋值就比较复杂了。如果我们没有定义默认拷贝构造函数,编译器会为我们定义一个默认的拷帐构造函数,默认拷贝构造函数执行的是浅拷贝,因此如果我们的类中有指针或复杂的数据类型,就需要自己定义实现拷贝构造函数。
2.4 委托构造函数
C++11中扩展了构造函数初始值的功能,因此我们可以定义所谓的委托构造函数。所谓委托函构造函数就是使用其所属类的其它构造函数扫行它自己的初始化过程。
class A{
//定义三个私有成员。
private:
int a;
int b;
int c;
public:
//非委托构造函数使用初始化列表进行值的初始化。
A(int a,int b,int c):a(a),b(b),c(c){}
//其他的构造函数全都委托给上面的构造函数进行初始化。
A():A(0,0,0){};
A(int a):A(a,0,0);
A(int a,int b):A(a,b,0);
}
2.5 移动构造函数
在c++11之前,用一个对象去初始化另一个同类的新对像,只能借助拷贝构造函数,C++在函数返回一个临时对象时,函数参数形实结合时,会调用拷贝构造函数,这时会执行拷贝操作,我们需要注意浅拷贝与深拷贝的问题,在执行拷贝的时候需要重新分配内存,这样就影响程序执行效率,如果对像拷贝完就销毁了,这种情况下,移动而非拷贝对像将会大幅提升性能。
class A {
private:
int * a;
public:
//移动构造函数
A(A &&a){
this.a = a.a;
a.a = nullptr;
}
}