C++常用知识点总结

C++编译模式

“事先声明”、“分别编译”、“事后链接”

C++特性

迭代器 ++it,it++的源码

1) 前置返回一个引用,后置返回一个对象

// ++i实现代码为:
int& operator++()
{
    *this += 1;
    return *this;
} 

2) 前置不会产生临时对象,后置必须产生临时对象,临时对象会导致效率降低

//i++实现代码为:       
int operator++(int) 
{
    int temp = *this;    
    ++*this; 
    return temp;                   
} 

左值引用和右值引用

对左值和右值的一个最常见的误解是等号左边的就是左值,等号右边的就是右值。左值和右值都是针对表达式而言的,左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象

一个区分左值与右值的便捷方法是看能不能对表达式取地址,如果能,则为左值,否则为右值

在C++11中,区别表达式是左值或右值可以做这样的总结:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)

新增容器

std::forward_list,和 std::list 的双向链表的实现不同,std::forward_list 使用单向链表进行实现,提供了 O(1) 复杂度的元素插入,不支持快速随机访问(这也是链表的特点),也是标准库容器中唯一一个不提供 size() 方法的容器。

当不需要双向迭代时,具有比 std::list 更高的空间利用率

C++内存布局

https://link.zhihu.com/?target=https%3A//blog.csdn.net/laozhong110/article/details/6402574

类的非虚成员函数的访问

class CA
{
public:
       int fun()
     {

          int i = 0;
          return i;
     }
};

CA *pca = NULL; 

pca->fun();     //访问ok

C++中构造函数,拷贝构造函数和赋值函数的区别和实现

一句话记住三者:对象不存在,且没用别的对象来初始化,就是调用了构造函数;

                对象不存在,且用别的对象来初始化,就是拷贝构造函数(上面说了三种用它的情况!)

                 对象存在,用别的对象来给它赋值,就是赋值函数。

参考https://blog.csdn.net/zcyzsy/article/details/52132936

C++中的虚函数表实现机制以及用C语言对其进行的模拟实现

参考https://blog.twofei.com/496/

成员列表初始化效率高?

对于在函数体中初始化,是在所有的数据成员被分配内存空间(并初始化)后才进行的。列表初始化是给数据成员分配内存空间时就进行初始化

前者是初始化、赋值;后者是初始化;少了一个步骤,当然更快;

类成员变量初始化时按照类中声明的顺序初始化的,而不是按照初始化列表的排序方式。

静态成员变量要在类外初始化呢?

答:因为静态变量在main之前就已经在全局数据段产生的,它不应该去依赖类对象的生命周期。若是在类内初始化,说明需要等待该类实例化才初始化。因此在类外初始化,程序编译时就已完成。

空类会添加哪些东西?

拷贝(缺省、拷贝、赋值)、析构

Empty(); // 缺省构造函数//
Empty( const Empty& ); // 拷贝构造函数//
~Empty(); // 析构函数//
Empty& operator=( const Empty& ); // 赋值运算符//

C++构造函数体内初始化与列表初始化的区别

本文探讨C++构造函数体内初始化与列表初始化的区别:
结论是
若某个类(下文的class B)有一个类成员是类类型(下文的class A),那么
1、若类B通过构造函数体内初始化,会先调用类A的默认构造函数(无参构造函数),再调用类A的赋值运算符;
2、若类B通过初始化列表去初始化,则只调用类A的拷贝构造函数。
另外,虽然对于成员类型是内置类型的情况,通过上述两种情况去初始化是相同的,但是为了标准化,推荐使用初始化列表。
 

以下几种情况必须使用初始化列表去初始化类成员:

当初始化一个reference member时,即成员类型是引用。
当初始化一个const member时,即成员类型是常量。
当调用一个基类的constructor,而它拥有一组参数时。如果此时不使用列表初始化,那么就需要自己重载赋值运算符。
当调用一个类成员的constructor,而它拥有一组参数时。
若某个类成员没有定义无参构造函数,而定义了其它的构造函数,也必须使用初始化列表。

C++构造函数体内初始化与列表初始化的区别_西塔666的博客-CSDN博客_c++列表初始化与构造函数区别

C++ 内存分配(new,operator new)详解

参考C++ 内存分配(new,operator new)详解 - 王小北 - 博客园

智能指针线程安全问题

为什么多线程读写 shared_ptr 要加锁? - 陈硕的Blog - C++博客

总结,“析构”算写操作;先找出公共资源对象,然后构造多线程对这个公共资源进行读写,比如share_ptr g是公共资源, share_ptr a = g 在A线程里面读它, 在B线程里面share_ptr b已经管理了一个资源, 然后g=b, 两个线程的对g的读和写其实都用多个步骤,拆分下来问题很多

Boost.SmartPtr: The Smart Pointer Library - 1.73.0

面试题:写一个不能被继承的类,且能正常使用

主要参考链接

C++面试宝典(1) - 知乎

你可能感兴趣的:(c++)