写在前面本文是我在学习c++的过程中整理出来的一些自己比较模糊的知识点,主要记录自己的学习过程,方便今后复习查阅。本文将持续更新。
1、运算符优先级
优先级由高到低:
.成员选择(对象)
->成员选择(指针)
++后置自增运算符
–后置自减运算符
从左到右结合
*取值运算符
&取地址运算符
++前置自增运算符
–前置自减运算符
从右到左结合
2、free()函数
用来释放动态分配的内存,如malloc()。必须要有指针指向malloc()动态分配的内存,否则容易出现野指针
3、memcpy()函数
函数原型 void *memcpy(void * dst , void * src, size-t size)
函数作用:将src所指的内存单元拷贝到dst所指的内存单元,一共拷贝size个字节。
4、类模板
类模板的意义
一些类主要用于存储和组织数据元素,因此类模板就是为了数据结构而诞生的,将泛型编程的思想应用于类,使得类的思想不关注数据类型的具体类型,而只关注类所需实现的功能。使用类模板的典型类如:数组类、链表类、Stack 类、Queue 类等。
类模板的声明
template <模板参数表>//模板参数表通常用关键字 calss 或者 typename声明
class 类名
{
类成员声明}
如果需要在类模板以外定义其成员函数,则需要采用以下的形式:
template<模板参数表>
返回值类型 类名<模板参数标识符列表>::函数名(参数表)
类模板示例:
5、NULL 和 nullptr的区别
1、在C语言中,NULL通常被定义为:#define NULL ((void *)0)。
所以说NULL实际上是一个空指针,如果在C语言中写入以下代码,编译是没有问题的,因为在C语言中把空指针赋给int和char指针的时候,发生了隐式类型转换,把void指针转换成了相应类型的指针。
int pi = NULL;
char pc = NULL;
2、C++程序中的NULL
因为C++是强类型语言,void是不能隐式转换成其他类型的指针的,以上代码编译器编译会报错,所以实际上编译器提供的头文件做了相应的处理:
#define NULL 0
3、 c++中nullptr
解决NULL代指空指针存在的二义性问题,在C++11版本(2011年发布)中特意引入了nullptr这一新的关键字来代指空指针,从上面的例子中我们可以看到,使用nullptr作为实参,确实选择了正确的以void作为形参的函数版本。
6、c++中 = delete和 = default的用法
=delete用法:参考原文链接:https://blog.csdn.net/lmb1612977696/article/details/80035487
1. 禁止使用编译器默认生成的函数
编译器默认为一个类生成的默认函数有:
默认构造函数
默认析构函数
默认拷贝构造函数
默认赋值函数
移动构造函数
移动拷贝函数
假如上面的几个函数中,不想使用其中某个,可以将其定义为private,或者使用=delete。
2.delete 关键字可用于任何函数,不仅仅局限于类的成员函数
3. 模板特化:在模板特例化中,可以用delete来过滤一些特定的形参类型
例如:Widget 类中声明了一个模板函数,当进行模板特化时,要求禁止参数为 void* 的函数调用。按照私有不实现思路,应该是将特例化的函数声明为私有型。
=default的含义:
struct Sales_data{
//新增的构造函数
Sales_data() = default;
Sales_data(const std::string &s):bookNo(s){}
//一些数据成员
std::string bookNo;
unsigned units_sold = 0;
};
解释Sales_data() = default的含义:首先请明确一点,该函数不接受任何参数,所以它是一个默认构造函数,我们定义这个函数的意义仅仅是因为我们既需要这个形式的默认构造函数又需要其他形式的构造函数,在C++11新标准中,如果我们需要默认的行为,那么可以通过在参数列表后面写上=default来要求编译器生成构造函数。其中,=default既可以和声明一起出现在类内部,也可以和定义一起出现在类外部。和其他函数一样,如果=default在类的内部,则默认构造函数是内联的;如果它出现在类的外部,则该成员默认情况下不是内联的
7、析构函数什么时候会被调用
1、对像生存周期结束时,对象被销毁
2、delete指向对象的指针时,或者delete对象的基类类型指针,并且基类的虚构函数被声明为虚函数时
3、对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。
8、构造函数可以重载,析构函数不可以重载
9、浅拷贝-造成内存泄漏的一种情况
浅拷贝又叫值拷贝,本质上来说拷贝的目标对象和源对象用的是同一份实体,只是引用的变量名不同而已,访问的还是同一块内存空间。假设有一个String类:
String s1; //定义一个string类的对象s1
String s2(s1);//定义string类型的对象s2,调用拷贝构造函数用s1初始化s2
在进行拷贝构造的时候将对象s1里的值全部拷贝到对象s2里。此时若类中没有重载拷贝构造函数,当进行对象赋值操作时编译器会调用默认拷贝构造函数,这就是浅拷贝。
//默认拷贝构造函数的原型
STRING( const STRING& s )
{
_str = s._str;
}
//默认赋值运算符函数原型
STRING& operator=(const STRING& s)
{
if (this != &s)//不允许自己赋值给自己
{
this->_str = s._str;
}
return *this;
}
当声明一个类有指针成员时,或者构造函数中有使用new开辟的空间时,该类对象之间直接赋值会导致:
1、被赋值对象中的指针丢失原始指向的内存,造成内存泄漏问题。
2、对象被销毁时调用析构函数,两次都释放的是同一块内存,导致程序崩溃。
#include "stdafx.h"<