您的位置:首页 > 编程语言 > C语言/C++

C++基础知识整理(2)

2016-09-10 14:28 260 查看
访问限定符:public, protected, private。不考虑继承,在类中,protect和private的效果是一样的。

对象成员:某类的对象作为另一个类的数据成员,该数据成员叫做这个类的对象成员。

某类中有对象成员,实例化该类时,先调用对象成员的构造函数,再调用该类的构造函数;销毁该类对象时,先调用该类对象的析构函数,在调用对象成员的析构函数。

深拷贝:拷贝构造函数需要在堆中实例化对象,并将参数中对象的数据成员拷贝给堆中的对象。

浅拷贝:拷贝构造函数将参数中对象的数据成员拷贝给实例化的对象。

this指针:指向自身对象的指针。当某对象调用其数据成员时,是将自己的this指针隐式的传递给形参,形参隐式的利用this指针来操作成员函数和数据成员。

常成员函数:在成员函数()后添加关键字const,就将该成员函数变成了常成员函数,常成员函数不能修改自身的数据成员。因为编译器会将const移动到隐含的参数this指针前来修饰this指针所指的对象,形式为const 类名 &this,这样this指针指向的对象就是常对象,是不能被修改的。

继承:派生类继承了基类的成员函数和数据成员。继承分三种,公有继承,私有继承,受保护继承。

公有继承:基类的public访问限定符下的成员被派生类继承在public访问限定符下,基类的protected访问限定符下的成员被派生类继承在了自己的protected下,基类的private不能被继承。

私有继承:基类的public和protected下的成员被派生类继承在了private访问限定符下。

受保护继承:基类的public和protected下的成员被派生类继承在了protected访问限定符下。

覆盖:在多态情况下,派生类虚函数表中本来指向基类虚函数的函数指针被派生类指向自己的虚函数指针覆盖。简而言之,在多态情况下,派生类的虚函数覆盖掉了基类的虚函数。覆盖的生成条件是:多态-函数名相同-覆盖

隐藏:在继承关系中,若派生类和基类的数据成员或成员函数同名,则基类中的数据成员和成员函数被隐藏,若要求调用基类的数据成员或成员函数,需加上基类的作用域。隐藏的生成条件是:继承-函数名相同-隐藏。

虚析构函数的作用:当析构函数为虚函数时,基类指针指向了派生类,若释放基类指针所指向的内存,则会实现析构函数多态,此时会调用派生类的析构函数,之后再调用基类构造函数。这样可以防止内存泄漏。

多重继承:继承的层次多

多继承:继承的基类多

虚继承:为了解决菱形继承带来的数据冗余,提出了虚继承。虚继承的方式是在继承类型前加关键字virtual。

利用宏定义解决重复定义。可在.h文件中通过宏定义来解决从定义问题:方法为在开头写上ifndef define …代码… endif这个宏定义即可。

面向对象的三大特征:封装,继承,多态。

多态:不同对象调用同一名称的函数产生不同的行为。多态产生的基础:1.虚函数 2.继承。

静态多态(重载)(早绑定)

动态多态(晚绑定)

虚析构函数:virtual修饰的析构函数

virtual不能修饰的有:一、普通函数。二、静态函数。三、构造函数。四、内联函数。

虚函数表:含有虚函数的类实例化时,会生成一个虚函数表和指向该表的虚函数指针。派生类继承了基类,若派生类中没有同名的虚函数,派生类实例化时,也会产生一个虚函数表和指向该表的虚函数指针。虚函数表中存放的是指向虚函数的函数指针。若派生类没有同名虚函数,则派生类中虚函数表中的虚函数指针指向基类函数中的虚函数,若派生类中有同名虚函数,则派生类中的虚函数表中的虚韩帅指针指向自己的虚函数。若有一个基类指针指向了派生类,当它调用虚函数时,因为它指向的是派生类对象,所以它会查找派生类对象的虚函数表指针,根据虚函数表指针找到虚函数表,通过查表找到虚函数从而执行。虚函数表指针存放在内存对象所占内存空间的最开头。

对象的大小:对象的数据成员所占内存的大小。若对象没有数据成员,则系统会为该对象分配一个字节的内存单元用来标记该对象的存在。

纯虚函数:没有函数体的虚函数且小括号后边加上 =0.在虚函数列表中,指向纯虚函数的函数指针被赋0.

抽象类:含有纯虚函数的类。抽象类不允许实例化对象。因为抽象类中的纯虚函数无意义。

RTTI:run time type identification.运行时类型识别。用到的函数是typeid(对象)。typeid()用来查看对象的数据类型,它返回一个type_info对象的引用。dynamic_cast<转换后类型>(转换对象),其参数只能为指针或引用,转换的类型中必须包含虚函数,转换成功,返回子类的地址。

多态的核心:虚函数表。

c++异常处理:通过throw 和 try…catch…配合使用。被调函数throw一个异常,主函数通过try…catch…进行捕获。若要捕获异常值,则catch的参数应为对象的引用。

常见的异常:一、数组下标越界 二、除数为0 三、内存不足

全局函数(普通函数):定义在类外,不是类的一部分,不需要在类中进行声明的函数。

友元全局函数:类内声明普通函数为友元,该函数就是该类的有元函数。

友元成员函数:类内声明某类的成员函数为有元,该函数就成为该类的友元函数。注意,在类中声明友元成员函数时,需要在该友元函数名前加类的作用域 类名::

友元类:类A在其内部声明friend B,即类B是类A的友元,友元类的所有成员都是该类的友元成员函数。

友元函数的权利:可以访问该类的私有,公有,受保护的数据成员和成员函数。

友元注意事项:一、友元不可传递 二、友元的关系是单向的 三、可以有很多友元

静态数据成员:是类的一部分,随类而生,所有对象共享。静态数据成员只有一份儿,不随对象的变化而变化,静态数据成员必须在类为单独初始化。

静态成员函数:不传this指针,所以不能操作非静态的成员函数和数据成员。

在声明中加入static关键字,在定义时不加。

静态成员函数不能加const,因为它没有传this指针。

编译器会将常成员函数中的const关键字改造到隐式传递的this指针定义之前,将this指针指向的对象设定为常对象。而静态成员函数根本就没有this指针,当然不能和const同时使用了。

运算符重载:关键字operator.

不能重载的运算符有:.运算符, ?:三目运算符,sizeof()运算符,.*运算符。

运算符重载分为成员函数运算符重载和友元运算符重载。

[]索引运算符只能进行成员函数运算符重载。cout输出运算符只能进行友元函数运算符重载。

后加运算符++的重载定义办法是 类名 operator++(int)形式,与前加进行区分,且不能用返回值引用。

成员函数运算符重载,返回*this对象,友元函数运算符重载,直接返回对象。

函数模板:关键字有三个template typename class,其中typename和class的作用是相同的,表示数据的类型。所以函数模板中的数据类型可以写成typename,也可以写成class。

形式如下:

template<typename T>
T max(T a, T b)
{
return a > b ? a : b;
}


上边的这个形式叫做函数模板,程序员将模板写好,编译器会自动生成相应数据类型的代码(函数),生成的代码叫做模板函数(实例化的函数模版)。其中肩括号<>中表达的是传递类型的参数。

变量也能做为参数传递给函数模板,形如:

template<int size>
void print()
{
out << size << ends;
}


将这个函数模板实例化,需要给类型参数中传递一个整型,形如: print<3>();它就会打印3这个值。

模板的参数可以为多个,但typename不可省略且typename和class可以混合使用。

51. 类模板,形如:

hljs css">class 类名
{
private:
T m_iCnt;
}


需要注意的是,在类外实现类模板的数据成员和成员函数时,头上必须加上template且需在成员名前写上作用域template::成员名。

形如:

template <typename T, class T, int size>
返回值类型 template<typename T, class T, int size>::成员函数名(参数)
{
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++基础