Rin的面经知识点

Static 用法

详细
1 . 静态变量 – 静态局部变量
(1)该变量在全局数据区分配内存(局部变量在栈区分配内存);
(2)静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化(局部变量每次函数调用都会被初始化);
(3)静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0(局部变量不会被初始化);
(4)它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,也就是不能在函数体外面使用它(局部变量在栈区,在函数结束后立即释放内存);

这里举个例子:
如果是普通 int a = 1;函数fun每次执行,这里 a = 1;
如果static int a = 10;a–;
第一次执行 a = 10,第二次再来fun, a = 9;

2 . 静态全局变量
(1)静态全局变量不能被其它文件所用
3.静态函数
(1)静态函数不能被其它文件所用;
(2)其它文件中可以定义相同名字的函数,不会发生冲突;

4. 静态成员变量
(1)牵一发而动全身,属于类而不是对象。静态数据成员只分配一次内存
5.静态成员函数
1.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
2.非静态成员函数可以任意地访问静态成员函数和静态数据成员;
3.静态成员函数不能访问非静态成员函数和非静态数据成员;
4.调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以用类名::函数名调用(因为他本来就是属于类的,用类名调用很正常)

4和5可以通过类名直接调用,class.fun(),不需要通过对象

一个头文件静态变量两个cpp用

模块作用域。static修饰变量的同时进行初始化,限制变量使用范围为定义它的模块(h,cpp),不是整个程序。
如果是静态变量,两个cpp互不干扰。然名称一样,但编译时已是不同的静态变量。
静态变量是定义即初始化,不写自动是 0 。
在这里插入图片描述

const

const 修饰成员函数

(1)const 类成员函数中不能修改类的成员变量,const 修饰的是 this 指针指向空间的内容

class Date
{
public:
    void GetDay(void);
private:
    int m_year;
    int m_month;
    int m_day;
};
 
void GetDay(void) const
{
    return m_day;
}

(2)如果想要取消常量性 mutable

class Date
{
public:
    void GetDay(void);
private:
    mutable int m_year;
    int m_month;
    int m_day;
};
 
void GetDay(void) const
{
    m_year = 2018;
    return m_day;
}

在这里插入图片描述
https://www.cnblogs.com/loliconinvincible/p/12535515.html

在这里插入图片描述

new 和 delete

new的使用(new 和 array new)

new 用于单个对象或者实例的创建,就是调用类的构造函数
new[]用于创建对象或实例的数组实例,并且地址是连续
释放内存时,new使用 delete,而new[]则对应delete[]。
但是,有些情况使用new[] 和 delete 不会有问题。

char* s = new char[100];
delete s;//没有影响

MyClass* p = new MyClass[10];
delete p;//出问题了

指针指向简单类型,如int、char等,其结果只不过是这块内存被回收,此时使用delete[]与delete没有区别,但如果p指向的是复杂类型,delete[]会针对动态分配得到的每个对象调用析构函数,然后再释放内存。所以第二种,构造了10个,析构了一个,直接bug。

如何知道 指针 指向对象的数组的大小?怎么知道调用几次析构函数?

C++ 的做法是在分配数组空间时多分配了 4 个字节的大小,专门保存数组的大小,在 delete [] 时就可以取出这个保存的数,就知道了需要调用析构函数多少次了。

这也解释了上面内置类型array new 却不使用 array delete的原理。内置类型在 new [ ] 时就没必要多分配那 4 个字节, delete [] 时直接到第二步释放为 int 数组分配的空间。此时跟直接delete是一样的。

new / delete 到底做了什么?

比如 A* a = new A;
三个步骤

  1. 调用operator new (sizeof(A)) – 分配内存
  2. 调用构造函数
  3. 返回指针

delete a;

  1. 调用 a 指向的对象的析构函数
  2. 调用operator delete – 释放内存
调用析构函数的次数是从数组对象指针前面的 4 个字节中取出;

传入 operator delete[] 函数的参数不是数组对象的指针,是 指针的值减 4。

operator new 和 operator delete

operator new三种形式
throwing (1)    
void* operator new (std::size_t size) throw (std::bad_alloc);
nothrow (2) 
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) throw();
placement (3)   
void* operator new (std::size_t size, void* ptr) throw();

(1)(2)的区别仅是是否抛出异常,当分配失败时,前者会抛出bad_alloc异常,后者返回null,不会抛出异常。它们都分配一个固定大小的连续内存。
(3)是placement new,它也是对operator new的一个重载。多接收一个ptr参数,但它只是简单地返回ptr。

placement new

比起前两个,只是调用分配内存,对象的地址你是不能决定的。placement new 的好处就是,在用户指定的内存位置(这个指针的位置)上构建新的对象。减少了内存碎片,已分配好的内存上进行对象的构建,构建速度快。

operator delete 两种形式

几乎与 operator new 前两中形式是一样的,但是参数是void*,返回值为void。c++其实有placement delete,但是官方的解释 是 “Does Nothing”。

operator new 的重载

A* p = new A; 如果 A 类重载了 operator new 呢?new 使用的第一步会调用谁?
结论:调用重载的版本,没有就调用全局版本
重载遵循作用域覆盖原则,即在里向外寻找operator new的重载时,只要找到operator new()函数就不再向外查找,哪怕参数不对,不对就直接bug咯。

函数重载本质

(1)特征标不同

返回值算重载吗?

两个同名函数,函数特征标不同,那么就是重载。返回值不同不能算作重载。这个特征标是指:参数个数,参数类型, 参数顺序不同

编译器如何解决重名问题?
编译器神奇的操作 - - 名称修饰,编译器将这重载的函数进行名称的一种加密
在这里插入图片描述
在这个修饰里也没有考虑返回值,所以,返回值不一样,编译器以为还是一个函数。
不过返回值不划入范围的好处是,不必联系上下文,确定重载的函数

int func(int a);
double func(int a);

如果这种成立,那么返回值需要提前定义好,编译器还要根据上下文判断返回值类型,再去调用函数。不便独立出来
int a = 6;
int ans1 = func(a);
double ans2 = func(a);

const算重载吗

分情况。
1.

int print(int a)
{
	cout<<"int"<<endl;
	return a;
}
int print(const int a)
{
	cout<<"const"<<endl;
	return a;
}

int a 与 const int a 一样
报错。
对于 a 而言,函数调用中存在实参和形参的结合。加入我们用的实参是int a,那么这两个函数都不会改变a的值,这两个函数对于a来说是没有任何区别的,所以不能通过编译,提示重定义。

2 .

void fun(char *a)  
{  
  cout << "non-const fun() " << a;  
}  
   
void fun(const char *a)  
{  
  cout << "const fun() " << a;  
}  

(char *a) 与 (const char *a) 不一样
正确。。因为char *a 中a指向的是一个字符串变量,而const char *a指向的是一个字符串常量,所以当参数为字符串常量时,调用第二个函数,而当函数是字符串变量时,调用第一个函数。

但是注意,非const变量赋值给const合法,第二个版本可以接收const, 但是第一个只能接收非const

3 .

void fun(char *a)  
{  
  cout << "non-const fun() " << a;  
}  
   
void fun(char * const a)  
{  
  cout << "const fun() " << a;  
}  
   

char *a 与 char * const a一样
报错。两个都是指向字符串变量。
Tips:如int &i 和const int & i 也是可以重载的

引用参数如何算重载?
void func(int & a);
void func(const int & a);
void func(int && a);

是重载。

其中,第一个,参数可以是可修改的左值
第二个是可修改或不可修改的左值,或右值
第三是右值

int x = 5;
const int y = 6;
func(x);// 第一个
func(y);//第二个
func(x + y);//第三个
但是第二个也可接收右值,所以如果第三没有定义,最后一句调用的就是第二个

(2)作用域限定

不载同一作用域,重名函数特征标不同不算重载。

void f(int);

void g()
{
        void f(double);
        f(1); //这里调用的是f(double),而不是f(int)
}

内层作用域的函数会隐藏外层的同名函数!同样的派生类的成员函数会隐藏基类的同名函数!!
所以派生类中虚函数不写virtual ,依然是虚函数!

(挖坑)

(3)参数匹配

int print(int a);
string print(string a);

那如果我写的是
print(3.0);
如何匹配?

c++ 会实验标准类型转换强制匹配,那么,使用int 的那个。

emplace_back() 与 push_back() 的区别?

底层实现的机制不同。push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

#include <vector> 
#include <iostream> 
using namespace std;
class testDemo
{
public:
    testDemo(int num):num(num){
        std::cout << "调用构造函数" << endl;
    }
    testDemo(const testDemo& other) :num(other.num) {
        std::cout << "调用拷贝构造函数" << endl;
    }
    testDemo(testDemo&& other) :num(other.num) {
        std::cout << "调用移动构造函数" << endl;
    }
private:
    int num;
};

int main()
{
    cout << "emplace_back:" << endl;
    std::vector<testDemo> demo1;
    demo1.emplace_back(2);  

    cout << "push_back:" << endl;
    std::vector<testDemo> demo2;
    demo2.push_back(2);
}
emplace_back:
调用构造函数
push_back:
调用构造函数
调用移动构造函数

在此基础上,将 testDemo 类中的移动构造函数注释掉,再运行程序会发现,运行结果变为:

emplace_back:
调用构造函数
push_back:
调用构造函数
调用拷贝构造函数

由此可以看出,push_back() 在底层实现时,会优先选择调用移动构造函数,如果没有才会调用拷贝构造函数。

### RIN Issue in MATLAB Relative Intensity Noise (RIN) is a critical parameter that measures the fluctuations of optical power relative to the mean power level over time. In MATLAB, handling and analyzing RIN involves several steps including data acquisition, preprocessing, and analysis techniques. For addressing specific issues related to RIN within MATLAB, one should consider using specialized toolboxes such as Communications Toolbox or RF Blockset which provide functions tailored for signal processing tasks involving noise characteristics[^1]. These toolboxes offer comprehensive tools designed specifically for simulating and measuring various types of noises present in communication systems. Additionally, when interfacing with external simulation environments like Lumerical through APIs, it's important to ensure proper synchronization between different platforms especially regarding variable exchange formats since these variables could include diverse data structures ranging from simple numeric values up to matrices depending on context requirements[^2]. To effectively tackle an RIN issue: - Utilize appropriate built-in functions provided by MATLAB’s Communication System Toolbox. - Ensure accurate conversion and interpretation of exchanged variables while working across multiple software interfaces. ```matlab % Example code snippet demonstrating basic approach towards calculating RIN signalPower = abs(signal).^2; % Calculate instantaneous power meanPower = mean(signalPower); % Compute average power rinValues = (signalPower ./ meanPower) - 1; % Obtain normalized intensity fluctuation stdDeviationOfRin = std(rinValues); % Measure standard deviation indicating severity of RIN ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值