(0人评价)
UE4 C++ 学习路线(上):标准C++
价格 ¥ 2998.00

类模板的成员函数本身就是模板函数,无需再次声明。

[展开全文]

1、类型限制在于函数对于该参数做了什么操作

[展开全文]

临时对象

接管(不拷贝,使原先对象失去内存控制权)

C++ 右值引用

赋值运算符左边:左值(地址)

赋值运算符右边:右值(内容)

右值引用:对临时对象的引用

语法:

s3=s1+s2;

hz::string_pro& lstr = s3;

hz::string_pro&& rstr = s1+s2;

 

移动语义:提高性能,并且不需要改变语法。

 

const string_pro& another

string_pro&& another

不能用const,因为我们需要修改another的内容与指针

[展开全文]

1、C字符串最后字符为/0

2、字符串后面预留空间,这样追加字符性能高

[展开全文]

1、初始化对象时:

hz::string_pro s1="hi";

hz::string_pro s2("hello");

均调用同一构造函数,两种操作等价。

2、拷贝该构造函数

hz::string_pro s2(s1);

编译器会默认生成一个拷贝构造函数,但是通常会造成编译问题,因为其拷贝方式是逐位拷贝,只包含成员变量,不包含堆上内存数据。如果成员变量指向同一段内存,而析构时会出现两次析构,针对同一段内存进行delete操作。

3、什么时候需要拷贝构造函数:

(1)需要用一个对象对新建对象进行初始化时

(2)函数中使用对象传值作为形参输入

(3)函数将对象传值作为返回值

 

4、编译器生成的赋值运算符:逐位拷贝

hz::string_pro s2;

s2=s1;

 

5、拷贝构造函数与赋值运算符是成对出现的

[展开全文]

1、堆(heap) GB/TB级别

2、静态变量 全局变量 既不在堆上又不在栈上

3、hz::string_pro s1 = "hihi";

s1本身在栈上,管理内存在堆上

4、std::cout<<sizeof(hz::string_pro)<<" "<<sizeof(s1)<<std::endl;

string_pro 两个int类型的成员变量,所以大小为8;虽然s1对象被初始化为“hihi”理论上应该输出8+4=12,但是sizeof()只计算栈上内存,不计算堆上内存。

 

5、在编译阶段就可以确定函数占用内存的大小,栈上操作仅仅相当于移动指针,但是堆上操作比较慢,需要向操作系统申请内存。(可能有百倍的差距)

6、动态分配内存:指定一个大小,分配指定大小的内存

[展开全文]

1、多线程安全:12306买票,显示还有票,但是实际上没有了。解决措施:加锁操作(本身违背多线程思想)可能导致死锁发生(A需要B占用的资源,B需要A占用的资源,如果加锁,则对象对数据操作期间无法被剥夺,会陷入循环等待)

2、资源管理原则 RAII

class Lock{

Lock(){

      pread_mutex_lock();

}

//伟大的析构函数!跟对象生命周期一致,作用域结束,抛出异常

~Lock(){

      pread_mutex_unlock();

}

};

//数据库打开关闭,网络打开与关闭

 

3、Resource Acquisition Is Initialization

资源获取即是初始化

[展开全文]

1、zero-overhead abstraction

零开销抽象,C++提供更多抽象机制,但不增加开销。

2、函数定义直接写在头文件里面,默认内联

3、delete nullptr 是允许的,如果delete后面接一个空指针则无事发生

4、_data = new char[clen];

..........

delete[] _data;

new[] 对应 delete[] (针对数组)

new 对应 delete   (针对对象)

5、new char[0] 也是允许的

[展开全文]

1、std::string,拥有字符串

std::string_view,仅存储起始指针和长度

2、std::wstring 宽字符串用来存储汉字,有可能是2个字节,或者4个字节,这个跟系统位数有关

3、Utf-8是变长编码,最长占6个字节,最短占1个字节

4、如果对象是一个const类型,则被调用的其成员也要声明为const类型

[展开全文]

1、运算符重载作用:让用户自定义的类也能使用内置的运算符

2、字符串重载“=”时,采用的是复制操作

3.s1.operator+=(s2);

 s1.operator[](0)='q'; 

4、加法运算符重载不是成员函数,定义为非成员函数可以扩大有效范围。

5、operator“+”支持string类型与C字符串相加

6、运算符重载必须要有一方是用户自定义类型

7、cout<<s1<<s2;

operator<<(operator<<(cout,s1),s2);

8、//bool类型转换运算符重载

while(cin){

    cin>>num;

}

9、不能被重载的运算符

作用域运算符::

点操作符(访问类对象).

点星操作符(访问成员对象指针).*

条件运算符?:

逻辑运算符具有短路求值的特性,而运算符重载相当于函数调用,这就失去了短路求值的特性。

PS:前置运算符与后置运算符重载

后置为++

前置为++(int)

[展开全文]

new 的啥类

delete时候找哪个类

如果析构函数是虚函数则调用其派生类

[展开全文]

1、多继承子类会继承所有基类成员变量(protected\public)

2、菱形继承(钻石继承)touchable在tapscroll中有两份,如果多继承层数较多,则子类对象会发生膨胀。解决办法:在中间继承类定义的冒号后面加上virtual

[展开全文]

1、抽象基类:像具体动物只有猫狗猪这样的具体对象,没有动物对象,我们不想让Animal生成对象,就要把该基类声明为抽象基类。具体方法就是在里面加上纯虚函数。例如:virtual void yoll()=0;

2、析构函数的调用顺序按照继承关系的反顺序

与构造函数调用顺序正好相反。

3、虚析构函数的作用

Animal* anim = new Dog;

delete anim;

delete anim; 如果基类中的析构函数不是虚函数,则将直接调用基类中的析构函数,不会调用派生类中的析构函数。

[展开全文]

1、对齐操作 2m48s(总线宽度限制 32位 4字节)

2、成员变量存放顺序按照声明顺序 5m23s

3、重写(override) 9m15s

4、virtual 虚函数声明

5、子类函数后面加上override

6、运行时决定虚函数到底调用哪个函数

7、如果不用虚函数,子类无法重写父类函数的行为

8、编译时,积累与派生类中每一个yoar()函数都生成唯一的一个标识符

9、对于非虚函数的函数,编译过程中就已知了调用的具体函数内容

10.sizeof() 子类与父类,子类将继承父类的public与protected的成员变量,virtual虚函数会引入一个指针 vptr->vtable

[展开全文]

授课教师

老师

课程特色

视频(56)
作业(94)