S18用于大型程序的工具

STM32与Futaba遥控器进行S.Bus的通讯程序 Futaba(日本双叶电子工业,戏称“扶他爸”)的遥控器用航模中使用较为广泛的遥控器。S.Bus则是Futaba公司提出的舵机控制总线。本篇博文主要以T6K为对象,介绍STM32与S.Bus协议的遥控器进行通讯的实例。 图1 Futaba T6K-V2 1、硬件电路 硬件上,它基于RS232协议,但高位取反(低电平表示1;高电平表示0),即信号反相。SBUS采用负逻辑,所以无论接收还是发送都要进... 阅读详情

S18用于大型程序的工具


一、异常处理

1、抛出异常
C++中,通过抛出(throwing)一条表达式来引发(raised)一个异常,被抛出的表达式的类型以及当前的调用链共同决定了哪段处理代码(handler)将被用来处理该异常

注意:当执行一个throw时跟在throw后的语句不再被执行,程序控制权将转移到与throw匹配的catch模块,意味着1.沿着调用链的函数可能会提早退出;2.一旦程序开始执行异常处理代码,则沿着调用链创建的对象将被销毁

(1)栈展开

  • 当抛出异常后,程序暂停执行并立刻开始寻找处理代码,若处于一个try块内,则检查与之关联的catch子句,若找到匹配的catch子句则进入执行,否则若没有找到匹配的catch子句且这个try块外还有try块,则到上一层try块的catch子句中继续查找(查找会从当前函数退出到上一层函数中),不断向外层try块展开查找catch子句的过程为栈展开
  • 最终找到了匹配的catch子句,则执行完毕后从当前try关联的所有catch子句后开始继续执行
  • 最终没有找到,程序将调用标准库函数terminate终止程序的执行

注意:一个异常如果没有被捕获,则它将终止当前的程序

(2)栈展开过程中对象被自动销毁
栈展开可能伴随着从一个函数回退到上一个函数,则局部对象会被自动销毁,类类型的析构函数会被自动调用,若是在构造过程中发生异常,也要确保已构造的那一部分被正确销毁

(3)析构函数与异常
析构函数可能在栈展开过程中被调用,因此析构函数不能抛出自身无法处理的异常,否则若析构函数抛出异常且自身无法处理则程序会被终止

(4)异常对象
异常对象是一种特殊的对象,编译器使用异常表达式对异常对象进行拷贝初始化,throw语句的表达式必须是完全类型的,且如果表达式是类类型则必须有一个可访问的析构函数和一个可访问的拷贝/移动构造函数,当异常处理结束后异常对象会被销毁

注意:当抛出一条表达式时,其静态编译类型决定了异常对象的类型,因此当一条表达式解引用一个基类指针时,若实际指向派生类则抛出的对象会被切掉一部分,只有基类的部分被抛出

注意:若抛出指针则要求在任何对应的处理代码存在的地方,指针所指的对象都必须存在

2、捕获异常
(1)异常声明
catch子句中的异常声明类似一个包含形参的函数形参列表,声明的类型决定了处理代码能捕获的异常类型,当进入一个catch语句后通过异常对象来初始化异常声明中的参数

注意:通常情况下,如果catch接受的异常与某个继承体系有关,则尽可能将该catch的参数定义成引用类型,否则若用某派生类的异常对象初始化基类的异常声明,会导致异常对象被切掉一部分

(2)查找匹配的处理代码
throw语句与catch的匹配是基于栈展开顺序的,因此最终选择的catch未必是最佳匹配,若存在继承关系,则处理派生类异常的代码必须在处理基类异常的代码之前,与函数匹配不同,绝大多数类型转换在catch匹配中是不允许的,只允许以下:

  • 允许non-const向const的类型转换,即非常量对象的throw语句可以匹配接受常量引用的catch语句
  • 允许从派生类向基类的类型转换
  • 数组被转换成指向首元素的指针,函数被转换成指向函数类型的指针

(3)重新抛出
一条catch语句通过重新抛出可以将异常继续传递给另一个catch语句,重新抛出通过一条不包含任何表达式的throw;完成,只能在catch语句或catch直接/间接调用的函数内重新抛出,异常将沿着调用链向上传递
(4)捕获所有异常的处理代码
catch的异常声明用...可以捕获所有异常,与任意类型的异常匹配

注意:由于catch(...)能捕获任意异常,当与多个catch一同出现时必须位于最底部

3、函数try语句块与构造函数
由于构造函数是先执行初始值列表,再执行函数体的,因此在初始值列表抛出的异常无法在函数体中catch执行,必须采用函数try语句块(函数测试块)

template <typename T>
Blob<T>::Blob(initialize_list<T> il)
    try: data(make_shared<vector<T>>(il)
{...}
catch(const bad_alloc &e)
{handle_err(e);}

**注意:若是在初始化构造函数的参数时发生异常,例如调用Blob的构造函数并正在初始化参数il时发生的异常,则不属于后面的try,而是属于函数调用者的部分,应该在函数调用者的上下文中得到处理

4、noexcept异常说明
(1)不抛出异常
noexcept显式说明一个函数不会抛出异常,有利于编译器执行一些特殊的优化,noexcept说明符应出现在对应函数的所有声明和定义中,位于尾置返回类型之前,类的成员函数中noexcept应位于const/引用限定符&和&&之后,位于final/override/虚函数=0之前
(2)违反异常说明
一旦一个noexcept函数抛出了异常,程序会调用terminate以确保遵守不在运行时抛出异常的承诺
(3)异常说明的实参
noexcept可以接受一个bool类型的实参,若实参等价于true则不会抛出异常,若等价于false则可能会抛出异常
(4)noexcept运算符
noexcept也是一个一元运算符,返回一个bool类型的右值常量表达式,用于表示给定的表达式是否抛出异常

void f() noexcept(noexcept(g()));  //若g()及g()调用的函数不会抛出异常,则noexcept(g())为真,则f()也不抛

(5)异常说明与指针、虚函数和拷贝控制

  • 若函数指针有noexcept声明,则其只能指向也有noexcept的函数,若函数指针没有noexcept,则两者都可指向
  • 若虚函数有noexcept声明,则其派生的虚函数也必须noexcept,若虚函数没有noexcept,则派生函数都可有无noexcept
  • 合成拷贝控制成员时,也生成一个异常说明,若对所有成员和基类的所有操作都承诺noexcept,则合成的也是noexcept
  • 定义析构函数而没有给定异常说明时,会生成一个异常说明

5、异常类层次
(1)标准库的异常类
继承体系最顶层是exception,表示某处出错但细节未知,runtime_error一般指只有运行时才会检测到的错误,logic_error一般指在代码中检查会发现的错误
(2)书店应用程序的异常类

class out_of_stock :public runtime_error     //栈溢出只有运行时才会发生,继承自runtime_error
{
public:
    explicit out_of_stock(const string &s) :runtime_error(s) {}
};
class isbn_mismatch :public logic_error      //isbn不匹配一般是代码检测就可以发现的,继承自logic_error
{
public:
    explicit isbn_mismatch(const string &s) :logic_error(s) {}
    isbn_mismatch(const string &s, const string &lhs, const string &rhs) :logic_error(s), left(s), right(s) {}
    const string left, right;
};

(3)使用自定义的异常类型

二、命名空间

注意:多个库将名字放置在全局命名空间中将引发命名空间污染

1、命名空间定义
(1)格式
由namespace起头,随后是命名空间的名字,然后在一对花括号中声明各种会出现在全局作用域中的名字,例如类、变量及其初始化操作、函数及其定义、模板和其他命名空间(嵌套),命名空间的花括号后不需要分号

注意:命名空间既可以定义在全局作用域内,也可以定义在其他命名空间中,但是不能定义在函数或类的内部

(2)每个命名空间都是一个作用域

注意:通常不把#include放在命名空间内部

(3)命名空间可以是不连续的
与其他作用域不同,同一个名字的命名空间可以不连续的在不同位置,使得可以将几个独立的接口和实现文件组成一个命名空间

  • 命名空间的一部分成员的作用是定义类,以及声明作为类接口的函数及对象,则这些成员应该置于头文件中,这些头文件将被包含在使用这些成员的文件中
  • 命名空间成员的定义部分则置于另外的源文件中

(4)定义命名空间成员
命名空间中定义的成员可以在命名空间中直接使用名字无须前缀,命名空间外定义的成员必须使用有前缀的名字
(5)模板特例化
模板特例化必须定义在原始模板所属的命名空间中,和其他命名空间类似,只要在命名空间中声明了特例化,就能在命名空间外部定义它了,但是需要带上命名空间前缀
(6)全局命名空间
全局作用域中定义的名字(即在所有类、函数及命名空间外)被隐式的定义在全局命名空间中,同样可以用作用域运算符,但没有前缀只有运算符

::member_name;      //member_name是全局的

(7)嵌套的命名空间
内层命名空间声明的名字将隐藏外层命名空间声明的同名成员,在嵌套的命名空间中定义的名字只在内层命名空间中有效,外层命名空间中的代码要想访问它必须在名字前添加限定符(除了内联命名空间)
(8)内联命名空间
在命名空间第一次定义的位置前加上inline,后续再打开这个命名空间时就不必写inline,而是自动隐式内联,外层命名空间访问内层内联命名空间时不需要前缀,可以直接使用
(9)未命名的命名空间
在namespace后没有名字的是未命名的命名空间,拥有静态生命周期,一个未命名的命名空间在一个文件内可以不连续,但是不能跨越多个文件,若在头文件中有未命名的命名空间,则所有包含该头文件的各自有这个命名空间里名字的不同实体,与其他命名空间不同

注意:未命名的命名空间没有前缀,也不需要作用域运算符来访问

2、使用命名空间的成员
(1)命名空间的别名
在命名空间定义后使用namespace space_name = alias_name;来建立别名,必须在命名空间定义后才可以声明别名
(2)using声明:扼要概述
using声明引入的名字从声明的位置开始,到using声明所在的作用域结束为止

注意:在类的作用域中,这样的声明语句只能指向基类成员

(3)using指示
using指示以using namespace space_name;使得命名空间中的名字全部可见,但是不能出现在类的作用域中
(4)using指示与作用域
using指示一般被看作是出现在最近的外层作用域中

namespace blip
{
    int i = 16, j = 15, k = 23;
}
int j = 0;
void manip()
{
    using namespace blip;    //using指示,将blip中的名字“添加”到了最近的外层作用域,即全局作用域中
    ++i;                     //blip::i变为17
    ++j;                     //二义性错误,由于using指示使j也有全局作用域的效果,此时是::j还是blip::j?
    ++::j;                   //::指出是全局作用域的j,此时::j为1
    ++blip::j;               //blip::指出是blip空间中的j,此时blip::j为16
    int k = 97;              //隐藏掉blip::k
    ++k;                     //局部的k为98
}

注意:当using指示导致一个命名空间中的名字与被注入的作用域中名字存在冲突是允许的,但是当使用冲突的名字时需要指名所处的命名空间,否则会导致二义性错误

(5)头文件与using声明或指示
头文件若有using则会导致所有包含该头文件的文件都被注入这些名字,因此头文件最多只在其函数内部或命名空间内使用using

注意:尽可能避免using指示,但是在命名空间本身的实现文件中就可以使用using指示

3、类、命名空间与作用域
(1)命名空间内部的名字查找:遵循常规规则,由内向外逐层查找到最外层才终止,且只有位于开放的块中且在使用点之前声明的名字才被考虑

注意:除了类内部出现的成员函数定义之外,总是向上查找作用域

(2)实参相关的查找与类类型形参
当给函数传递一个类类型对象的对象/引用/指针时,除了在常规的作用域查找外还会查找实参类所属的命名空间,这个特别规则使得允许概念上作为类接口一部分的非成员函数无须单独的using声明就能被程序使用
(3)查找与std::move和std::forward
由于move和forward是接受右值引用形参的函数模板,可以匹配任意类型,因此move和forward引起的名字冲突非常常见,且由于move/forward本身执行非常特殊的功能,因此使用时必须带上std前缀,即std::move/std::forward
(4)友元声明与实参相关的查找
当类声明一个友元时,该友元声明并没有使得友元本身可见,然而若友元接受一个类的参数,则会因为这个参数而能找到函数

namespace A
{
    class C
    {
        //两个友元,在友元声明之外没有其他声明
        //这些函数隐式称为namespace A的成员
        friend void f2();        //除非另有声明,否则不会被找到
        friend void f(const C&); //根据实参有C,可以查找到f
    }
}

int main()
{
    A::C cobj;
    f(cobj);                     //正确,通过A::C中的友元声明找到A::f
    f2();                        //错误,A::f2未被声明
}

4、重载与命名空间
(1)与实参相关的查找与重载
函数调用时,由于会到实参所属的命名空间查找函数,因此每个实参类(包括实参类的基类)所属命名空间找到的同名函数都将被添加到候选集中(即使某些函数在调用语句所在处不可见也是如此)
(2)重载与using声明
using只是声明一个名字,不应该带上参数列表等其他元素

  • 进行using声明时,函数的所有版本都被引入到当前作用域
  • using声明出现在某个作用域时,将隐藏外层作用域的同名声明
  • 若using所在作用域已经有一个与using将要引入的函数同名且同形参列表,则没有指名命名空间的调用将导致函数调用二义性错误

(3)重载与using指示
类似using声明,using指示则是将命名空间中所有内容都提升到所在作用域中
(4)跨越多个using指示的重载
若有多个using指示,则每个命名空间的所有内容都提升到所在作用域,来自每个命名空间的同名函数都会成为候选函数集

三、多重继承与虚继承

多重继承是指从多个直接基类中产生派生类的能力,多重继承的派生类继承了所有父类的属性

1、多重继承
(1)多重继承的派生类从每个基类中继承状态
每个基类包含一个可选的访问说明符,多重继承的派生类表同样只能包含已经定义过的类(且这些类不能是final的),并且在具体某个给定的派生列表中,同一个基类只能出现一次,派生类的对象包含每个基类的子对象
(2)派生类构造函数初始化所有基类
构造一个派生类对象将同时构造并初始化其所有基类子对象,同样,派生类的构造函数也只能初始化其直接基类

class Bear : public ZooAnimal {...};
class Panda : public Bear, public Endangered {...};

//隐式调用Bear默认构造函数,显式调用Endangered构造函数,Panda的构造顺序ZooAnimal->Bear->Endangered->Panda
Panda::Panda(string name, bool onExhibit) : Endangered(Endangered::critical) { } 

注意:基类的构造顺序与派生列表中基类的出现顺序保持一致(参考以派生类为根,一个/多个最终基类为叶节点的DFS顺序,就是构造顺序),与构造函数中初始化顺序无关

(3)继承的构造函数与多重继承
C++11允许使用using class_name::class_name来继承非默认、非拷贝、非移动的构造函数,若在多重继承中继承了不同基类的具有相同形参列表的构造函数,则出现错误,此时必须显式定义具有相同形参列表的派生类构造函数

struct Base1
{
    Base1() = default;
    Base1(const string &);
    Base1(shared_ptr<int>);
};
struct Base2
{
    Base2() = default;
    Base2(const string &);
    Base2(int);
};
struct D1: public Base1, public Base2
{
    using Base1::Base1;         //从Base1继承构造函数
    using Base2::Base2;         //从Base2继承构造函数
    //发生冲突,Base1(const string &)和Base2(const string &)具有相同形参列表
};
struct D2: public Base1, public Base2
{
    using Base1::Base1;         //从Base1继承构造函数
    using Base2::Base2;         //从Base2继承构造函数
    D2(const string &s): Base1(s), Base2(s) { }   //重新定义自己的构造函数
    D2() = default;             //D2定义了自己的构造函数,编译器就不会合成默认构造函数,必须指定默认构造函数
};

(4)析构函数与多重继承
与单继承相同,派生类的析构函数只负责清楚派生类本身分配的资源,派生类的成员及基类都是自动销毁的,析构函数的调用顺序与构造函数相反
(5)多重继承的派生类的拷贝与移动操作
与单继承相同,多重继承的派生类如果定义了自己的拷贝/赋值构造函数和赋值运算符,则必须在完整的对象上执行拷贝/移动/赋值操作(即每个基类也必须有这些操作)

2、类型转换与多个基类
(1)与单继承类似,可以令某个可访问基类的指针/引用直接指向一个派生类对象

注意:由于派生类向多个基类的转换是同样好的,因此对于接受不同基类引用/指针的同名函数,调用会出错

(2)基于指针类型或引用类型的查找
一个对象/引用/指针的静态类型决定了哪些成员是可见的,名字查找的顺序,参考S15面向对象程序设计.六.1如下

假定调用p->mem()或p.mem()
1.首先确定p的静态类型(引用、指针、对象)
2.在p的静态类型对应的类中查找mem,如果找不到则依次到直接基类中不断查找直至顶端,若一直找不到则编译器报错
3.若找到了mem则进行函数匹配的常规类型检查,已确认本次调用是否合法
4.若调用合法,则编译器根据mem是否是虚函数产生不同的代码:如果mem是虚函数且是通过指针调用的(p->mem()),则将在运行时确定到底运行该虚函数的哪个版本,依据对象的动态类型;如果mem不是虚函数或是通过对象调用的(p.mem(),p不是引用,若引用则会动态绑定),则进行常规函数调用

3、多重继承下的类作用域
在单继承的情况下,查找过程沿继承体系自底向上,派生类的名字隐藏基类的同名成员;在多继承的情况下,查找过程在多条继承链中并行自底向上查找,(可以视当前类为树根,多个直接基类就是多个树的分支)若在超过一个直接基类的链中找到同名成员,则不加前缀的调用具有二义性,需要明确指出使用哪个版本(从多个基类分别继承同名成员本身是合法的,只是调用需要指名具体版本)

4、虚继承
(1)同一个类的多个子对象
虽然继承列表不允许出现多个相同的类,但是可以间接继承自同一个类

注意:由于有多个相同的子对象,因此使用这个子对象中名字时若不指名具体继承链,则二义性错误

(2)虚继承
虚继承的目的是令某个类做出声明,愿意共享它的基类,则共享的基类子对象称为虚基类,不论虚基类在多少继承链上出现多少次,最终在派生类中只包含唯一一个虚基类子对象

注意:虚派生只影响从指定了虚基类的派生类中进一步派生出来的类,而不会影响派生类本身的,即例如A是基类,虚继承A->B,虚继承A->C,虚继承并不影响B或C,多重继承B+C->D则D受影响只有一份A

(3)使用虚基类
在派生列表中添加关键字virtual(与访问限定符的相对先后不影响)
(4)支持向基类的常规类型转换
无论基类是不是虚基类,派生类对象都能被可访问基类的指针/引用操作
(5)虚基类成员的可见性
假设有继承关系如下虚继承B->D1, 虚继承B->D2, D1+D2->D,且B中定义了成员x,则通过D访问x可能有

  • 若D1/D2都没有x,则D访问x解析为B的成员,不存在二义性,D只有一个B对象(虚基类)
  • 若D1或D2有一个有x,则D访问x解析为D1或D2中的成员,不存在二义性,由于继承中名字隐藏,D1或D2中的x隐藏了虚基类B的x
  • 若D1/D2都有x,则D访问x二义性错误,两条继承链上都有x,解决方式是D定义自己的x

5、构造函数与虚继承
(1)虚继承的对象的构造方式
在虚派生中,虚基类是由最底层的派生类初始化的(而常规继承中每个类都只能调用直接基类的构造函数进行初始化),含有虚基类的对象的构造顺序:首先使用提供给最底层派生类的构造函数的初始值初始化该对象的虚基类子对象,接下来按照直接基类在派生列表中出现的次序对其进行初始化

注意:虚基类总是先于非虚基类构造,与它们在继承体系中的次序和位置无关,并且若没有显示调用虚基类的构造函数,则会自动调用虚基类的默认构造函数

(2)构造函数与析构函数的次序
一个类可以有多个虚基类,这些虚基类的子对象按照它们在派生列表中出现的顺序依次构造;
编译器按照直接基类的声明顺序检查,若有虚基类,则按顺序及层次先构造虚基类,然后再按顺序及层次构造非虚基类;合成的拷贝/移动构造函数及合成的移动赋值运算符中的成员也按该顺序执行,析构函数调用顺序是构造的逆序

//虚继承练习18.29-18.30:
/* v for virtual
 *
 *       Class---------|
 *          \          |
 *         Base        |
 *        v/  v\       |
 *       D2    D1      |
 *         \  /        |
 *          MI    /-----
 *           \   /
 *           Final
 */  
class Class
{
public:
    Class() { cout << "Class()" << endl; }
};
class Base : public Class
{
public:
    Base() : ival(0) { cout << "Base()" << endl; }
    Base(int i) : ival(i) {}
    Base(const Base &b) : ival(b.ival) {}
protected:
    int ival;
};
class D1 : virtual public Base
{
public:
    D1() : Base() { cout << "D1()" << endl; }    //控制直接基类的初始化
    D1(int i) : Base(i) {}
    D1(const D1 &d) : Base(d) {}
};
class D2 : virtual public Base
{
public:
    D2() : Base() { cout << "D2()" << endl; }
    D2(int i) : Base(i) {}
    D2(const D2 &d) : Base(d) {}
};
class MI : public D1, public D2
{
public:
    MI() : Base() { cout << "MI()" << endl; }    //注意!除了控制直接基类的初始化,还要控制虚基类的初始化
                                                 //虚基类由最底层派生类控制初始化
    MI(int i) : Base(i), D1(i), D2(i) {}
    MI(const MI &m) : Base(m), D1(m), D2(m) {}
};
class Final : public MI, public Class            //warning C4584: 'Final': base-class
                                                 //'Class' is already a base-class of 'MI'
{
public:
    Final() : Base() { cout << "Final()" << endl; }   
    Final(int i) : Base(i), MI(i) {}
    Final(const Final &f) : Base(f), MI(f) {}
};
int main()
{
    Final F;  //Final中有1个Base,2个Class
    return 0;
}
//输出如下:
Class()
Base()
D1()
D2()
MI()
Class()
Final()
《多模态融合改进》支持目标检测、目标分割、OBB、姿态估计,配置教程 本文以为例,讲解如何配置,支持替换专栏里所有的改进方式。 阅读详情

相关推荐

台达伺服B3驱动器参数的设定和CN1的接法

3. B2的电子齿轮比是直接设定P1-44(分子)和P1-45(分母)就就可以的,但是B3的有个隐藏的细节,就是P1-44的默认值77216不用去更改,这是官方客服说的,需要改的是P1-45这个参数,比如说,我使用的丝杆螺距是5mm的,那么就是以5000脉冲走完5mm为一圈,则就把P1-45设定为5000即可;我的是三菱FX3S系列的PLC,是NPN型的,输出点是24V-作为信号的,所以接41、37,具体可参考B3的。,跟着客服的讲解操作才解决的,以下就是解决方法,希望能够帮到需要的各位。

qq_38681017的博客 1万+

《C++ Primer》学习笔记 —用于大型程序的工具

《C++ Primer》学习笔记 —用于大型程序的工具一、异常处理1、异常与移动构造(1)条件1 — 非值传递(2)条件2 — 异常不能再次被抛出(3)条件3 — 异常对象的创建需要在当前异常块内2、try语句与构造函数 一、异常处理 1、异常与移动构造 我们在抛出异常时,可以使用类类型的对象。这要求类必须含有一个可访问的析构函数和一个可访问的拷贝或移动构造函数。最后这项要求很趣,这就是说我们可以没有拷贝构造函数而只有移动构造函数。 #include <iostream> using names

coding-hwz 296

ARM Memory Compiler实战指南:从参数配置到GDSII生成的全流程解析

本文详细解析了ARM Memory Compiler在SRAM设计中的全流程应用,从基础参数配置到GDSII文件生成。涵盖SRAM类型选择、核心参数配置策略、高级优化技巧及TSMC 28nm工艺下的实战案例,帮助IC设计工程师高效实现存储器模块的优化设计。

game4的博客 418

C++Primer5th 第十八章 用于大型程序的工具

第十八章 用于大型程序的工具 18.1 异常处理 18.1.1 抛出异常 栈展开 栈展开过程中对象被自动销毁 析构函数与异常 异常对象 18.1.2 捕获异常 查找匹配的处理代码 重新抛出 捕获所有异常的处理代码 18.1.3 函数try语句块与构造函数 18.1.4 noexcept异常说明 违反异常说明 异常说明实参 noexcept运算符 异常说明与指针、虚函数和拷贝控制 18.1.5 异常类层次 18.2 命名空间 18.2.1 命名空间定义 每个命名空间都是一个作用.

梦三岁的博客 826

汽车氛围灯 PCBA 方案开发:从技术底层解析车载光效的核心逻辑

摘要: 车载氛围灯PCBA方案开发需兼顾性能与车规要求。主控芯片选型应关注运算能力、温度适应性和低功耗(如NXPS32K344、复旦微FM33FG065A)。电路防护需采用TVS二极管等组合设计,满足ISO7637-2浪涌防护标准。通信协议分层应用(CAN+LIN),调光需解决色准与温漂问题,动态灯效通过FIFO队列实现。开发中需进行温度循环、振动、EMC等可靠性测试,细节处理(如三防涂覆)至关重要。该领域开发需熟悉车规标准并积累实车经验。

2401_87454052的博客 1132

基于freesurfer和3Dslicer的脑区分割与电极定位全流程解析(实战指南)

本文提供了一套基于FreeSurfer和3D Slicer的颅内电极定位实战指南。详细解析了从环境搭建、数据预处理、FreeSurfer脑区分割、影像配准,到3D Slicer中手动与自动化电极定位的全流程。重点介绍了如何利用FreeSurfer进行高精度脑区分割,并在3D Slicer中实现电极触点的可视化标记与坐标提取,最终获得带脑区信息的电极数据,为iEEG/SEEG研究奠定基础。

banana的博客 299

throw语句的使用简介

throw语句使用规则: • throw语句抛出错误  检查先前定义的条件时非常有用  表达式的类型必须是System.Exception或是它的派生类 throw语句代码例子: string DaySuffix(int days) { if (days < 0 || days > 31) ...

weixin_33885253的博客 442

[Github]GitHub 2FA快速安全配置全攻略

GitHub强制要求用户启用双重身份验证(2FA)以提升代码安全。本文详细介绍了2FA的三种实现方式:TOTP应用验证(推荐)、SMS短信验证(备用)和硬件安全密钥(最安全),并提供了配置指南。特别推荐使用在线工具2FA.run快速测试TOTP功能。文章还涵盖恢复代码管理、企业级2FA策略制定以及常见问题解决方案,如时间同步问题、多设备同步等。通过强制2FA、定期审计和建立安全事件响应流程,开发者可构建更安全的代码管理体系。

冰茶的博客 2621

C#中如何处理异常

throw语句 在学习如何处理异常之前,我们先介绍一下throw语句。 throw语句抛出一个异常: throw expression 带有表达式的throw语句抛出的异常是在计算这个表达式时产生的。这个表达式必须表示一个System.Exception类型或它的派生类型的值。如果对表达式的计算产生的结果是null,则抛出的将是一个NullReferenceException异常。 不带

chaojishuaigeli的专栏 779

别再纠结高侧低侧了!用INA199/INA219这类集成电流检测芯片,5分钟搞定精准电流测量

本文详细解析了使用INA199/INA219等集成电流检测芯片实现精准电流测量的高效方案。通过对比传统分立元件方案,突出集成芯片在精度、温度稳定性和设计简化方面的优势,并提供硬件设计避坑指南和软件实现最佳实践,帮助开发者快速掌握电流检测技术。

weixin_42685438的博客 471

从共现矩阵到共现图一步到位——详解版

1.共现矩阵 判断大量不同文本之间,相邻词的联系,两词在所有文本中相邻的次数在矩阵中用数值表示。(参考此) 例子如下: 1.1 文本 • I like deep learning. • I like NLP. • I enjoy flying. 1.2 共现矩阵 2.共现图 2.1 数据预处理(节点和边) 获取文件node.csv和edge.csv。代码详见github仓库 2.2 共现图的制作 2.2.1 gephi的安装(参考此) (1)先下载gephi (2) 再配置java环境(下载java1.8

微乐的博客 4402

18 c++ 用于大型程序的工具

#include <iostream> #include <vector> #include <tuple> #include <bitset> #include <regex> #include <random> using namespace std; void exceptionTest(); int main() { exceptionTest(); cout << "enter key" &lt

dabusidede的博客 271

ST-LINK调试STM32H743必看:CubeMX工程中缺失的这行代码导致程序跑飞

本文深入剖析了使用ST-LINK调试STM32H743时,因CubeMX工程中缺失电源电压档位配置代码而导致程序跑飞或出现“Can not access memory”错误的问题。文章解释了H7系列电源与时钟耦合的核心原理,提供了具体的代码修复方案和系统化的调试排查思路,帮助开发者从根本上解决这一常见调试困境。

weixin_29191669的博客 281

第 18 章 用于大型程序的工具

练习 18.1: (a):异常对象的类型是range_error。 (b):异常对象的类型是exception。 如果将(b)中的throw语句写成throw p,将会出现运行时错误。throw *p被抛出的异常对象是对指针p解引用的结果。若写成throw p,则抛出的异常对象是exception*类型。 练习 18.2: 指针p不会被释放,造成内存泄漏。 练习 18.3: class intArray { public: intArray(size_t n): p(new int[n]) {

qq_38359705的博客 195

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【免费下载】 博途V18-S7-1200 单部电梯六层电梯程序:高效、安全的电梯控制解决方案

博途V18-S7-1200 单部电梯六层电梯程序:高效、安全的电梯控制解决方案 【下载地址】博途V18-S7-1200单部电梯六层电梯程序 本资源文件提供了基于博途V18和S7-1200 PLC的单部电梯六层电梯程序。该程序旨在实现电梯的自动控制,能够及时响应不同楼层的客户召唤请求,并具备电梯初始化、启停、平层、开关门、...

gitblog_09760的博客 1555

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

真核生物 18S rRNA

与细菌多样性分析类似,在真核微生物中也有三类核糖体RNA(rRNA),包括5.8S rRNA、18S rRNA和28S rRNA。18S rRNA基因是编码真核生物核糖体小亚基的DNA序列,其中既有保守区,也有可变区(V1-V9,没有V6区)。保守区域反映了生物物种间的亲缘关系,而可变区则能体现物种间的差异,适用于作种级及以上的分类标准。其中,V4区是文献中常用的检测片段。 真核微生物18S rRNA基因组成及引物选择 真核微生物多样性分析流程图如下: 数据库:Silva,RDP 微基...

tinygene的博客 6732

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

第18章 用于大型程序的工具 18.2命名空间

18.2 命名空间 命名空间可以有效的防止变量名重复,命名空间就是一个作用域,可以在命名空间中定义命名空间,但是不能在类和函数中定义。 18.2.1 命名空间定义 使用这种方法来定义命名空间 namespace xxx{ } 命名空间都是一个作用域,所以和作用域中的变量是一样的,变量名字不能重复。 和作用域不一样的是,命名空间可以不是连续的。我们定义一个命名空间,如果之前没有这个空间,则创建这个...

大琪子的博客 203

【免费下载】 博途V18-S7-1200 单部电梯六层电梯程序

博途V18-S7-1200 单部电梯六层电梯程序 【下载地址】博途V18-S7-1200单部电梯六层电梯程序 本资源文件提供了基于博途V18和S7-1200 PLC的单部电梯六层电梯程序。该程序旨在实现电梯的自动控制,能够及时响应不同楼层的客户召唤请求,并具备电梯初始化、启停、平层、开关门、故障提示及上下限位保护等功能 ...

gitblog_09719的博客 969

【C++ Primer】第18章 用于大型程序的工具 (3)

本章介绍用于大型程序的 C++ 特性:多重继承与虚继承。

HPP_优快云的博客 432

移动端内存泄漏检测:Android S++ 与 iOS 18 的新工具

对于资源未释放的检测,工具会在资源对象(如文件句柄、网络连接等)的生命周期结束时,检查是否有对应的释放操作,若发现未释放的资源,同样会生成报告提示开发者。另一方面,跨平台的内存泄漏检测工具可能会成为趋势,以满足同时开发多个平台应用的开发者的需求,实现一次检测,多平台适用,提高开发效率。同时,随着人工智能和机器学习技术在移动开发领域的应用逐渐深入,内存泄漏检测工具可能会借助这些技术,实现对内存使用模式的智能预测,提前发现潜在的内存泄漏风险,将问题解决在萌芽状态,为移动应用的性能优化带来更大的提升空间。

2503_92849275的博客 5082

第18章 用于大型程序的工具

18.1异常处理 try { // actions that cause an exception to be thrown } catch (...) { // work to partially handle the exception throw; } 在C++中,通过throwing来raised一个exception。当throw时,thr...

weixin_30877227的博客 142

vivos18和s18pro区别 对比 评测

虽然主摄都是5000万像素,但S18使用的是豪威OV50E、1/1.55",反观S18 Pro则是索尼IMX920、1/1.55"。其传感器整体素质更好。另外,S18 Pro升级为5000万超广角(三星S5KJN1,1/2.76"),还多了一颗1200万像素长焦(索尼 IMX663,1/2.93")。前置上,S18和S18 Pro都是相同的5000万像素超光感镜头,采用三星S5KJN1、1/2.76"底传感器,也都有广角双柔光灯。区别在于,S18 Pro升级了蓝牙5.3和Wi-Fi 7,传输速度更快。

qq_49807938的博客 1512

奇迹 IGC MU S18 微端

闲暇时间开发的MuOnline IGC Season18迷你客户端,第一阶段功能完成,更多功能仍在继续开发中。

weixin_43350757的博客 2754

罗德NRP18S功率探头NRP18T

罗德NRP18S功率探头NRP18T。

weixin_68673733的博客 228

HTC G18 S-ON to s-off

很多机油买回HTC G18后才发现自己的手机是S-ON的,杯具了!!于是到处找刷S-OFF的教程,有木有?今天,为了帮机友们解决S-ON刷S-OFF的问题,特为大家整理了HTC G18 S-ON怎么刷成S-OFF详细图文教程,希望可以帮到有需要的机友! 关于ship s-off:什么是S-OFF? (以下s-off涉及到硬解和软解) S代表 Security Lock安全锁,保护锁的意思

XiyouMC 1035

魅族18pro和三星s21哪个好

很多人不知道魅族18pro和三星s21哪个好。魅族18pro自公布以来广受大家好评,那么和他价钱差不多的手机性能如何样呢?魅族18pro和三星s21参数对比是怎样的呢?下面一起来看看魅族18pro和三星s21对比区别评测。 1、屏幕对比 三星s21:搭载6.2英寸的AMOLED屏幕,分享120Hz的屏幕刷新,分享1080p分辨率; 魅族18pro:搭载6.7英寸的Super AMOLED屏幕,分享120Hz的屏幕刷新和240Hz的触控采样率。 小结:在手机的屏幕方面是魅族18的屏幕性能更好,为用户分

qq_40669242的博客 934
上一篇: S17标准库特殊设施
下一篇: S19特殊工具与技术
jasonyuchen
博客等级 码龄10年 27粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值