引言

c++11引用非常多的新的编程规范和语法我们进行看一下。

https://github.com/0voice

序列for循环:

简化代码,语法简洁且能避免数组越界,遍历普通数组和stl容器。

#include<iostream>
#include<vector>
using namespace std;
int main(){
//正常for循环
vector<int>a={2,234,23423,4,2,5,6,23};
for(int i=0;i<a.size();i++){
cout<<a[i]<<endl;
}
//序列for循环
for(auto x:a){
cout<<x<<endl;
}
return 0;
}

缺点:无法跳过某个位置。

Lambda表达式(匿名函数):

可以在需要的时候定义一个临时函数,无需声明,一般试用与stl算法的参数,qt后面的信号与槽用到,让代码更紧凑。

语法:[captyre list](parameter list) mutable exception->return type{function body}

[捕获列表](参数列表) mutable修饰符 异常说明->尾置返回类型{函数体}

名称作用案例
捕获列表定义 Lambda 表达式能否 / 如何访问其所在 “外部作用域” 的变量(如外部函数的局部变量、全局变量等)。

[=]:捕获外部全部变量

[&x,y]:引用捕获变量x,值变量捕获y

参数列表与普通函数的参数列表一致(int a, double b)
mutable修饰符默认情况下,Lambda 若 “值捕获” 外部变量,不允许修改这些变量;添加mutable后,允许在 Lambda 内部修改值捕获的变量(仅修改副本,不影响外部原变量)。
#include<iostream>
using namespace std;

int main() {
	int a = 0, b = 2;
	//没有加入关键字
	auto add = [&a, b]() {
		a++; //可以改变
		//b++;值是副本不可以改变
		cout << "a:" << a << "b:" << b << endl;
		};
		//加入关键字
	int a1 = 0, b1 = 2;
	auto add1 = [&a1, b1]()mutable {
		a1++; //可以改变
		b1++;// 值是可以改变的
		cout << "a1:" << a1 << "b1:" << b1 << endl;
		};
	add();
	add1();
	return 0;
}
异常说明声明 Lambda 表达式是否可能抛出异常,以及抛出哪些类型的异常(C++11 后常用noexcept表示 “不抛出任何异常”)。noexcept(声明此 Lambda 不会抛出任何异常)、throw(int, double)(声明可能抛出 int 或 double 类型的异常,C++17 后逐渐被noexcept替代)。
返回类型显式指定 Lambda 表达式的返回值类型。若 Lambda 体内只有一条return语句,编译器可自动推导返回类型,此时可省略该部分;若有多条return语句或需明确类型,需显式声明。->int(声明返回值为 int 类型)、->vector<string>(声明返回值为vector<string>类型)。
函数体Lambda 表达式的 “执行逻辑”,与普通函数的函数体一致,包含具体的代码语句{ return a + b; }

算法参数:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//正常操作
bool comparefunc(int a,int b){
return a>b;}
int main(){
vector<int> v1={2,6,1,7,8,9,0,4,5};
sort(v1.begin(),v1.end(),comparefunc);
for(auto i:v1){
cout<<i<<endl;}
vector<int> v2={2,6,1,7,8,9,0,4,9,5};
//lambda表达式
sort(v2.begin(),v2.end(),[](int a,int b) ->bool{return a>b});
for(auto i:21){
cout<<i<<endl;}
return 0;
}

委托构造和继承构造:

委托构造函数:

允许同一个类中的构造函数调用另一个构造函数。

作用:

  • 避免多个构造函数中重复编写相同的初始化代码;
  • 将初始化逻辑集中到一个 “基础构造函数” 中,其他构造函数通过委托复用该逻辑,仅处理自己的特殊参数。
#include<iostream>
using namespace std;
class MyClass{
private:
int x;
double y;
public:
//普通构造函数
MyClass(int a,int b){
x=a;
y=b;
cout<<"普通构造函数"<<endl;}
MyClass(int x):MyClass(x,0.0){
cout<<"委托构造函数一个参数的";
}
MyClass():MyClass(0,0.0){
cout<<"委托构造函数无参"<<endl;
}

};
int main(){
MyClass obj(20,20.6);
MyClass obj1;
MyClass  obj2(33);
return 0;
}

继承构造函数:

派生类继承基类的构造函数

作用:

  • 当派生类不需要修改基类构造函数的逻辑,仅需 “复用基类的构造函数来初始化基类部分成员” 时,避免重复定义;
  • 尤其适合基类有多个构造函数的场景(如基类有 5 个构造函数,派生类无需逐个重写)

语法:

通过 using 基类名::基类构造函数名(通常直接写 using Base::Base;)在派生类中声明继承基类的所有构造函数:

#include<iostreaam>
using namespace std;
// 基类
class Base {
private:
    int x;
public:
    Base() : x(0) {}
    Base(int a) : x(a) {}
    Base(int a, double b) : x(a) {}  // 基类有3个构造函数
};

// 派生类
class Derived : public Base {
private:
    int y;  // 派生类新增成员
public:
    // 继承基类的所有构造函数
    using Base::Base;  // 关键:声明继承基类构造函数

    // 派生类自己的构造函数(若需要)
    Derived(int a, int b) : Base(a), y(b) {}  // 同时初始化基类和派生类成员
};
int main(){
Derived d1;        // 调用继承的 Base() 构造函数(初始化基类x)
Derived d2(5);     // 调用继承的 Base(int a) 构造函数
Derived d3(3, 4.5);// 调用继承的 Base(int a, double b) 构造函数
Derived d4(2, 3);  // 调用派生类自己的构造函数
return 0;}

总结:

  • 普通构造函数是基础,负责类成员的直接初始化;
  • 委托构造函数是 “同类内的复用工具”,通过调用同类其他构造函数减少重复代码;
  • 继承构造函数是 “跨类(派生类与基类)的复用工具”,让派生类无需重写基类已有的构造函数。

垃圾回收机制:

c++里面没有垃圾回收机制,一般用于手动管理和确定性资源释放(rall)(智能指针,标准容器);

下面介绍在计算机科学方面4中垃圾回收机制:

算法名称核心思想主要优点主要缺点典型应用场景
引用计数算法为每个对象维护引用计数器,计数为 0 时立即回收1. 垃圾产生后立即回收(实时性好)2. 实现逻辑简单1. 无法解决循环引用(如 A 引用 B,B 引用 A)2. 每次引用操作需更新计数,有额外时间开销3. 每个对象需额外存储计数字段,占用空间C++ std::shared_ptr、Python(部分对象)
标记 - 清除算法1. 标记:从根对象出发标记所有可达对象2. 清除:回收未被标记的对象1. 可解决循环引用问题2. 适用于任意类型垃圾回收1. 需暂停程序(STW),影响实时性2. 回收后产生内存碎片3. 需遍历所有对象,效率随内存增大下降早期 Java GC、Boehm GC(C++ 第三方库)
分代回收算法按对象存活时间分为多代(如年轻代、老年代),不同代采用不同策略回收1. 针对 “多数对象存活时间短” 的特性优化,效率高2. 年轻代高频回收成本低,减少整体 STW 时间1. 实现复杂(需维护分代逻辑和对象晋升规则)2. 老年代全量回收时仍可能有较长停顿Java(G1、ZGC)、C# 垃圾回收
复制算法(节点拷贝算法)将内存分为两块,仅使用一块;回收时复制存活对象到另一块,清空原块1. 回收后内存无碎片(存活对象紧凑排列)2. 回收效率高(仅处理存活对象)1. 空间利用率低(始终有一半内存空闲)2. 存活对象多时,复制操作成本高分代回收中的年轻代(如 Java 年轻代的 Eden 区与 Survivor 区)

总结:

序列for循环用于遍历数组和stl容器

lambda表达式用于算法函数参数的使用,起到简化代码的。

委托构造和继承构造都是为了减少重复代码,提高代码的复用性。

上面的基本都是用与简化代码的。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐