new用法总结
new int;//开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针)
new int(100);//开辟一个存放整数的空间,并指定该整数的初值为100,返回一个指向该存储空间的地址
new char[10];//开辟一个存放字符数组(包括10个元素)的空间,返回首元素的地址
new int[5][4];//开辟一个存放二维整型数组(大小为5*4)的空间,返回首元素的地址
float *p=new float (3.14159);//开辟一个存放单精度数的空间,并指定该实数的初值为//3.14159,将返回的该空间的地址赋给指针变量p
友元函数
友元函数和普通函数区别:它能够操作类中的私有成员;
友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。类授予它的友元特别的访问权。
类外定义。
inline 内联函数
该函数的使用目的是为了节省调用函数开辟的栈空间,即直接调用函数。一般使用在函数体比较简单的情况下,如果函数体比较复杂,函数的执行本身开辟的栈空间要大于调用函数开辟的栈空间,调用inline已无意义。且inline使用在函数定义时,声明前使用无意义。
template声明模板
template <class T>/template <typename T>
关于继承
C++类成员如果不做说明,默认是private。
不管什么继承,子类都可以访问基类的protect和public成员。private继承只是表明继承关系是private的,通俗的说,private继承是指“外界”不知道那个类还有个父类,而不是子类自己也不知道他有个父类。就像私有成员一样,外界不知道类有私有成员,不代表类自己也不了解自己的私有成员。
Base objBase; // 基类对象
Derived objDer; // 派生类对象
Base* ptr = &objBase; // ptr 指向 Base 对象
ptr = &objDer; // ptr 执行 Derived 对象的 Base 部分
Base &ref = objDer; // ref 绑定到 Derived 对象的 Base 部分
初步了解C++继承,point:
1.子类public继承父类后,不能直接访问父类的private变量,但可以通过public提供的接口(如果有)来访问。
2.带有继承以及组合的类的构造函数顺序是: 父类的构造函数->组合成员对象的构造函数 ->子类自己的构造函数;
3.虚继承:理解:比如现在有一个沙发床,它既有床的属性又有沙发的属性,它们都有长宽高的属性,但是我们却只需要知道它的一个状态的属性。
4.private, public, protected 访问标号的访问范围。
private:只能由(1)该类中的函数、(2)其友元函数访问。 不能被任何其他访问,该类的对象也不能访问。
protected:可以被(1)该类中的函数、(2)子类的函数、以及(3)其友元函数访问。但不能被该类的对象访问。
public:可以被(1)该类中的函数、(2)子类的函数、(3)其友元函数访问,也可以由(4)该类的对象访问。
Lambda表达式:https://www.cnblogs.com/DswCnblog/p/5629165.html
[capture list] (params list) mutable exception-> return type { function body }
各项具体含义如下
- capture list:捕获外部变量列表
- params list:形参列表
- mutable指示符:用来说明是否可以修改捕获的变量
- exception:异常设定
- return type:返回类型
- function body:函数体
此外,我们还可以省略其中的某些成分来声明“不完整”的Lambda表达式,常见的有以下几种:
序号 | 格式 |
---|---|
1 | [capture list] (params list) -> return type {function body} |
2 | [capture list] (params list) {function body} |
3 | [capture list] {function body} |
其中:
- 格式1声明了const类型的表达式,这种类型的表达式不能修改捕获列表中的值。
- 格式2省略了返回值类型,但编译器可以根据以下规则推断出Lambda表达式的返回类型: (1):如果function body中存在return语句,则该Lambda表达式的返回类型由return语句的返回类型确定; (2):如果function body中没有return语句,则返回值为void类型。
-
格式3中省略了参数列表,类似普通函数中的无参函数。
STL模板类map和pair
可以简单理解为:map可以当做一个容器(装载具有一定格式的数据);pair可以理解为元素(放入到容器的的一个个个体),发现pair并没有单独行动的典型用法,正常都是配合map来使用(即把pair这个元素插入到map这个容器里面)
map<uint32_t, string> temp;
4 1. temp[1] = "template";
5 2.temp.insert(pair<uint32_t, string>(1, "template"));
6 3.temp.insert(make_pair(1, "template"));
7
8 pair实质上是一个结构体,其主要的两个成员变量是first和second,因此有了
for(const auto& i : temp) {
9 cout << "first = " << i.first; // i 也就是一个pair;
10 cout << "second = " << i.second;
11 }
12 pair需要指定构造的类型,make_pair可以隐式转换,即将1 转成uint32_t, template转成string类型。
关于子类在继承父类的构造函数时的一些情况:来源:;https://blog.csdn.net/koudan567/article/details/49805735
1. 子类没有定义构造方法,则调用父类的无参构造方法;
2.如果子类定义了构造方法,不论是无参数的还是带参数的,在创建子类对象的时候,首先执行父类的无参构造方法,然后执行自己的构造方法;
3.在创建子类对象的时候,如果子类的构造函数没有显示的调用父类的构造函数,则会调用父类的默认无参构造函数。
此处父类的默认无参构造函数是当用户没有定义的时候,编译器默认生成的构造函数。
4.在创建子类对象时,如果子类的构造函数没有显示调用父类的构造函数,自己提供了无参构造函数,则会调用父类自己的无参构造函数。 函数实现同第二种。
5.在创建子类对象时,如果子类的构造函数没有显示的调用父类的构造函数只定义了自己的有参构造函数,则会出错。(如果父类只有有参构造方法,则子类必须显示的调用此有参构造方法)
关于在类中声明自身类型成员变量问题
C++定义类时,不能在类中声明自身类型的成员变量,这是由于当实例化一个类的对象时,编译器会根据类的定义来分配相应的存储空间 。也就是说,在创建对象前,一定要有完整的类定义,这样编译器才能正确的计算所需空间。即以下情况会报错:
class Single
{
private:
Single single;
.......
}
下面情况不会报错:
class Single
{
private:
static Single single;
.......
}
在类定义时,类中声明指向自身类型的指针或引用作为内部成员没有问题,由于指针和引用所占存储空间大小与类型无关,所以编译器可以计算分配空间,所以正确。 下面一段代码,则编译通过:
class Single
{
private:
Single *single;
.......
}
大括号{ }内声明的变量,作用域只属于大括号内。
纯虚函数和虚函数
1.纯虚函数.表示为: class A: { virtual void fun() = 0; ...}在父类中不必实现函数体,但是子类中必须对其进行实现,否则编译报错。拥有纯虚函数的类是不能用来实例化的,只有子类实现了纯虚函数才有可能被实例化。
虚函数 必须在父亲类中进行实现(意为必须有{ },否则链接会报错)。子类中如果有实现,子类调用该函数时,则调用子类的实现方法;否则调用父类的实现方法。
一个对象用父类声明,用子类实例化
这个实例是子类的,但是因为声明时是用父类声明的,所以你用正常的办法访问不到子类自己的成员,只能访问到从父类继承来的成员。
在子类中用override重写父类中用virtual申明的虚方法时 ,实例化父类调用该方法,执行时调用的是子类中重写的方法;
类定义的先后次序问题
A类定义在B类的后面,且B类的一个属性成员是A类对象的指针或者引用,则在B类的定义之前应该先对A类进行一个声明。
class A;
class B { A a; }
class A { ... }
智能指针shared_ptr和make_shared, weak_ptr,
shared_ptr<int> aa = make_shared<int>();
weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象. 进行该对象的内存管理的是那个强引用的 shared_ptr. weak_ptr只是提供了对管理对象的一个访问手段. weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少.
std::shared_ptr<int> sp(new int(10));
std::weak_ptr<int> wp(sp);
wp = sp;
printf("%d\n", wp.use_count()); // 1
wp.reset();
printf("%d\n", wp); // 0
智能指针和普通指针转换
std::shared_ptr<int> ptr_test2 = std::make_shared<int>();
int* pTest2 = ptr_test2.get(); //shared_ptr转普通指针
int* pTest = new test();
std::shared_ptr<int> ptr_test = std::shared_ptr<int>(pTest); //普通指针转shared_ptr