一个简单的类
定义一个类
class MyClass //类名
{
public: //访问修饰符
MyClass(); //构造函数
~MyClass(); //析构函数
void function(); //成员函数,也叫成员方法
private:
int m_data; //成员数据
}; //不要忘了花括号后的分号
使用类
MyClass mc; //定义一个对象
mc.function(); //调用对象方法
六个的默认成员函数
构造函数、析构函数、拷贝构造函数、赋值运算符函数、取址运算符函数、const取址运算符函数。
类的成员函数
一般来说,声明在类内的函数称为类的成员函数。
当成员函数的定义在类内时,我们称这个函数为内联成员函数。编译时,编译器将程序中出现的内联函数的调用表达式,用内联函数的函数体进行替换。
成员函数有一个隐藏参数,this指针(除了静态成员函数)。
类的访问修饰符
类的成员在类内、友元函数|类、类外、派生类中的访问权限。Ps: √可以访问;×不可访问。
|
类内和友元 |
类外 |
派生类 |
公有成员(public) |
√ |
√ |
√ |
保护成员(protected) |
√ |
× |
√ |
私有成员(private) |
√ |
× |
× |
构造函数&析构函数
构造函数
在创建对象时调用;主要用于初始化成员变量,但最好使用 初始化列表 来初始化。同时,构造函数不能为虚函数,因为虚表是在构造函数中创建或更新的。
析构函数
在销毁对象时调用;主要用于释放资源,比如关闭文件、释放内存。
拷贝构造函数
使用之前创建的同一类型对象初始化新创建的对象。
使用场景:
1、创建新对象。显示拷贝
2、函数形参。隐式拷贝
3、函数返回值。
隐式拷贝 拷贝构造函数的一般形式
classname(const classname &obj)
{
//构造函数的主体
}
友元函数
友元函数定义在类的外部,但有权访问类的所有成员。尽管友元函数在类中有声明,但友元函数不是成员函数,更没有类的this指针。
给类添加友元
friend void fun(); //友元函数
friend class MyClass; //友元类
内联函数
引入内联函数的目的是为了解决程序中函数调用的效率问题。程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式,用内联函数的函数体进行替换。而对于其他的函数,都是在运行时候才被替代。这其实就是以空间换时间。所以内联函数一般都是1-5行的小函数。
this指针
每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。
继承
通过继承,派生类就拥有了基类的大部分成员。
注意,基类中的这些成员不会被派生类继承。
1、基类的构造函数、析构函数和拷贝构造函数。
2、基类的重载运算符。
3、基类的友元函数。
同时,派生类不能直接访问基类的私有成员,但可以通过基类公有或保护成员间接访问。
一个简单的继承
class ChildClass: public ParentClass
ChildClass为派生类(或子类),ParentClass为基类(或父类)。public为继承类型。
继承方式有三种,public、protected、private。默认为private。它们相应地改变了基类成员的访问修饰符。
继承方式 |
基类public成员 |
基类protected成员 |
基类private成员 |
public继承 |
public |
protected |
private(不可访问) |
protected继承 |
protected |
protected |
private(不可访问) |
private继承 |
private |
private |
private(不可访问) |
Ps:无论哪种继承方式,基类中私有成员在派生类中都不可访问。
重载运算符和重载函数
同一作用域内,一堆相似的操作,仅仅传入参数不同,这时就需要重载。
函数重载
只需函数名相同,参数不同(类型、顺序、个数),就构成了重载。
运算符重载
Box operator+(const Box&);