C/C++编程心得(二)

参考资料

https://en.cppreference.com/

这个网站可以查到C++的标准库的用法。

https://isocpp.org

这个是C++标准组织的网站,可以查看C++的新特性。

http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines

这个是C++新特性的代码规范指南

https://en.cppreference.com/w/cpp/compiler_support

这里可以查看各个编译器对于新特性的支持程度。

总结下来就是(2019.6):

  • C++ 11/14基本都支持了。

  • 硬件公司如Cray/Nvidia/Oracle(Sun)/IBM基本不支持C++ 17。

  • 能支持C++2a的就只有gcc、Clang、MSVC和EDG eccp了,其中MSVC支持的特性较少,而其他三者相对更新的比较勤。

https://www.edg.com/

这是EDG的官网。它是一家专门做C++前端的公司。因此,他们的更新和开源项目gcc/Clang一样勤,也就不足为奇了。

关于引用的一个常见错误

class Base
{
  public:
    void something(Base& b){}
};

int main()
{
  Base b;
  b.something(Base());
  return 0;           
}

上面的代码在编译时,会出现如下错误信息:

abc.cpp:12:20: error: no matching function for call to ‘Base::something(Base)’
abc.cpp:12:20: note: candidate is:
abc.cpp:6:7: note: void Base::something(Base&)
abc.cpp:6:7: note: no known conversion for argument 1 from ‘Base’ to ‘Base&’

这是由于Base()生成的是临时变量,将之赋值给一个non-const的引用是不行的。

解决方法是

void something(const Base& b){}

可以参看下文:

http://stackoverflow.com/questions/20247525/about-c-conversion-no-known-conversion-for-argument-1-from-some-class-to

typedef struct

在C中:

typedef struct Student
{
  int a;
}Stu;

于是在声明变量的时候就可:Stu stu1;

如果没有typedef就必须用struct Student stu1;来声明。

这里的Stu实际上就是struct Student的别名。

但是在C++中:

struct Student
{
  int a;
};

声明变量时可直接Student stu2;

所以当给C++的库提供C的接口时,经常可以看见如下用法:

typedef struct Student Student;

这样就可以抹平两者的差异了。

参考:

https://www.cnblogs.com/qyaizs/articles/2039101.html

struct和typedef struct彻底明白了

malloc与calloc

两者都是动态分配内存。

主要的不同:malloc不初始化分配的内存,已分配的内存中可以是任意的值。calloc初始化已分配的内存为0。

次要的不同:calloc返回的是一个数组,而malloc返回的是一个对象。

惰性求值

http://www.cnblogs.com/gtarcoder/p/4811614.html

c++11实现l延迟调用(惰性求值)

http://www.fuzihao.org/blog/2016/02/10/C-%E5%AE%9E%E7%8E%B0%E6%83%B0%E6%80%A7%E6%B1%82%E5%80%BC/

C++实现惰性求值

左值和右值

左值是可以放在赋值号左边可以被赋值的值;左值必须要在内存中有实体;

右值当在赋值号右边取出值赋给其他变量的值;右值可以在内存也可以在CPU寄存器。

一个对象被用作右值时,使用的是它的内容(值),被当作左值时,使用的是它的地址。

左值语法:type &引用名 = 左值表达式;

右值语法:type &&引用名 = 右值表达式;

C++11通过引入右值引用来优化性能,具体来说是通过move语义来将临时生成的左值中的资源无代价的转移到另外一个对象中去。

但右值引入也带来的新问题。

原来我们只有:

template void f1(T& t);

现在还有:

template void f2(T&& t);

不加限制的话,还会有T&& &(将T&&作为参数传给f1),所以就有了引用折叠(Reference collapsing)的概念,即:

& & => &
&& & => &
& && => &
&& && => &&

如果把上述规则看作logical-OR的话,那么&就是1,而&&就是0。

注意,因为临时变量是右值,所以T&&的类型在f2函数体内实际上就是T

std::move:无条件的转为右值引用。

std::forward:有条件的转为右值引用。

std::remove_reference:将T&T&&变成T

参考:

https://www.cnblogs.com/ldlchina/p/6608154.html

C++11右值引用和std::move语句实例解析

https://www.jianshu.com/p/b90d1091a4ff

C++11 std::move和std::forward

http://shaoyuan1943.github.io/2016/03/26/explain-move-forward/

详解C++11中移动语义(std::move)和完美转发(std::forward)

https://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c/

Perfect forwarding and universal references in C++

RAII

资源获取即初始化(Resource Acquisition Is Initialization),或称RAII,是一种C++编程技术,它将必须在使用前请求的资源(分配的堆内存、执行线程、打开的套接字、打开的文件、锁定的互斥体、磁盘空间、数据库连接等——任何存在受限供给中的事物)的生命周期绑定与一个对象的生存期相绑定。

C++标准库遵循RAII管理其自身的资源:类在构造函数中获取其资源(错误时抛出异常),并在其析构函数中释放之(决不抛出),而不要求显式清理。

RAII不适用于并非在使用前请求的资源:CPU时间、核心,以及缓存容量、熵池容量、网络带宽、电力消费、栈内存等。

RAII也是下面介绍的各类智能指针的理论基础。

参考:

https://mp.weixin.qq.com/s/m44zVWMvactsLPjKsFnlSg

RAII惯用法:C++资源管理的利器

GC in C++

https://www.hboehm.info/gc/

A garbage collector for C and C++(boehm gc)

https://blog.codingnow.com/2008/06/gc.html

引用计数与垃圾收集之比较

https://www.cnblogs.com/duguguiyu/archive/2007/11/14/959178.html

GC in C++

你可能感兴趣的:(C/C++编程心得(二))