CPP基础

1. 拷贝和移动

左值赋值类操作采用拷贝构造函数, 一般赋值都是拷贝构造函数, 初始化尽量使用 新式的{}初始化方式
右值赋值类操作采用移动构造函数,函数返回采用的是移动构造函数, 函数返回会使用移动构造函数产生一个临时变量,临时变量再赋值给 变量,若无移动构造函数,两次赋值均使用拷贝构造函数(均为采用右值赋值)。stb::move()可以取一个左值的右值

关于各种默认的构造函数:
https://docs.microsoft.com/en-us/cpp/cpp/constructors-cpp?redirectedfrom=MSDN&view=msvc-160

2.左值右值场景总结

&a 为右值,其中&取址符只能用于左值之前
同理 *a 为右值, *只能用于左值前面
本质上来说,右值指的是临时变量

T a = 默认是传值,即值拷贝
T& a = lvalue 其中a为左值引用
T&& a = rvalue 其中a为右值的引用

3.关于函数式编程中几个例子
// 使用模板的方式
template <typename  F>
double f(const vector<double>& origV, F subF ) {
  double max = *origV.begin();
  for (double i : origV ) {
      if (subF(i, max)) {
          max = i;
      }
    }
  return max;
}

// 使用using函数式声明方式
using FF = bool (*)(double x, double y);
using FFF = function<bool(double, double)>;
double ff(const vector<double>& origV,  FF subF) {
  double max = *origV.begin();
  for (double i : origV ) {
      if (subF(i, max)) {
          max = i;
      }
    }
  return max;
}


void showvec(const std::vector<double>& line) {
  cout << ff(line, [](double x, double y){ return x > y;}) << endl;   //  lambda 函数
//  for (auto iter = line.cbegin(); iter != line.cend(); iter++) {
//    cout << (*iter) << endl;
//  }
}
3.关于const 函数

如果采用"按址传递方式"的函数返回值加const 修饰,那么函数返回值(即地址)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。

如果采用"按值传递方式"的函数返回值加const 修饰,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。
  类的成员函数后面加 const,表明这个函数不可以对这个类对象的数据成员(准确地说是非static数据成员)作任何改变。 (const 对象只能调用const成员函数)

4. 关于内部链接 和 外部链接

符号可以在声明多次,但只能被定义一次

  • 外部链接:默认为外部链接

  • 内部链接:
    函数:static、inline
    变量:const、constexpr、static

  • inline (constexpr 修饰的函数默认是内联的)的内部性体现在 申明和定义必须在同一编译单元内存在,不会从外部去查找,但其编译链接存在一定的特殊性。这里具体选择哪一个编译单元的的版本,存在一定随机性,如果内联成功,则是各编译单元的版本,如果内联失败,则是随机选择一个版本,所以不同编译单元若定义不一致则其实际表现是未定义的,不通的编译配置下会选择不同的版本;实际inline成功的函数不能获取函数指针。
    最佳实践:
    在这里插入图片描述

参考:https://www.zhihu.com/question/458849130;https://zhuanlan.zhihu.com/p/380389282,结论如下:

https://zh-blog.logan.tw/2020/03/22/cxx-17-inline-variable/
在这里插入图片描述
https://en.cppreference.com/w/cpp/language/inline
在这里插入图片描述
在这里插入图片描述

  • static的内部性也必须是同一编译单元存在,不会从外部查找,但基本质是每个编译单元都会重新编译一个自己版本的函数
  • extern const定义变量 可以将const变量的从内部链接 提升为 外部链接
  • extern static 无效,仍是内部性
  • extern inline 用法比较奇怪, 建议少使用,可以参考:

对于非成员函数和变量,最佳实践是在头文件 中申明(变量采用extern),在源文件中定义;
凡属于在头文件中定义的变量函数,均需要考虑在多个源文件中引用的重定义问题;
函数采用 static inline可以变为内部性; 变量采用static const 变为内部性

5 修饰符
  • inline函数修饰可以只在申明和定义的移除出现, 由于内联优化, 需要保证 inline声明和定义在同一编译单元出现。比如对于类成员函数,inline申明的成员函数, 必须和类申明在同编译单元出现。
// comm.h
int Sum();

inline int Sum() {
  return 6;
}

// comm1.h
inline int Sum();
int Sum(){
retrun 6};
  • static成员函数修饰必须只在类声明中出现; static普通函数则需要申明和定义均有static修饰,由于 内部链接性,需要保证申明必须在同一编译单元
  • 函数的默认值只能在声明或定义中一处出现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值