类的六个默认成员函数
如果一个类中什么成员都没有,简称为空类。
空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
一.构造函数
构造函数(Constructor)
构造函数是 C++ 中用于初始化对象的特殊成员函数,它在对象创建时自动调用。以下是构造函数的全面解析:
1. 基本概念
- 作用:初始化对象成员变量
- 特点:
- 函数名与类名相同
- 无返回值(连 void 都没有)
- 支持重载(一个类可以有多个构造函数)
- 调用时机:
- 对象定义时( Class obj; )
- 动态创建对象时( new Class() )
- 临时对象创建时( Class() )
2. 构造函数的类型
(1) 编译器生成的默认构造函数
- 触发条件:当类没有定义任何构造函数时,编译器自动生成
- 行为:
- 对基本类型( int / float 等)不初始化(值随机)
- 对类类型成员调用其默认构造函数
class DefaultExample
{
public:
// 编译器自动生成默认构造函数
int val; // 未初始化
};
void demo()
{
DefaultExample obj; // val的值随机
}
(2) 自定义默认构造函数(无参构造)
class MyClass
{
public:
// 显式定义默认构造函数
MyClass() : x(0), y(0) {}
private:
int x, y;
};
(3) 全缺省构造函数
- 所有参数都有默认值,可以替代默认构造函数
class AllDefault
{
public:
// 全缺省构造函数(也是默认构造函数)
AllDefault(int a = 0, int b = 0) : x(a), y(b) {}
private:
int x, y;
};
void demo()
{
AllDefault obj1; // 等效于 AllDefault(0, 0)
AllDefault obj2(5); // AllDefault(5, 0)
}
(4) 部分缺省构造函数
class PartialDefault
{
public:
// 部分缺省参数
PartialDefault(int a, int b = 10) : x(a), y(b) {}
private:
int x, y;
};
void demo()
{
PartialDefault obj(5); // PartialDefault(5, 10)
PartialDefault obj2(1, 2);
}
3. 必须自定义构造函数的场景
在 C++ 中,以下情况必须手动编写构造函数,不能依赖编译器生成的默认构造函数:
_类包含引用类型成员
- 原因:引用必须在初始化时绑定到一个对象,且之后不能更改绑定目标。
- 解决方案:必须通过构造函数的初始化列表显式初始化引用成员。
_类包含 const 常量成员
- 原因:const 成员必须在对象构造时初始化,且之后不可修改。
- 解决方案:必须在构造函数的初始化列表中初始化 const 成员。
_类需要管理动态资源
- 原因:默认构造函数不会自动分配堆内存、打开文件等资源。
- 典型场景:
- 成员包含指针并需要动态分配内存(如 int* data = new int[100] )
- 需要初始化文件句柄、数据库连接等外部资源
- 解决方案:在构造函数中显式申请资源,并在析构函数中释放。
_类成员需要特定初始值
- 原因:编译器生成的默认构造函数不会初始化基本类型成员(如 int / float 等)。
- 解决方案:手动定义构造函数,确保成员初始化为预期值(例如初始化为 0 或空字符串)。
_类继承体系中基类没有默认构造函数
- 原因:如果基类只有带参数的构造函数,派生类必须显式调用基类构造函数。
- 解决方案:在派生类构造函数的初始化列表中调用基类的构造函数。
_需要禁止某些对象的构造方式
- 场景:
- 希望强制使用特定参数构造对象(如必须传入 ID)
- 单例模式中需要私有化构造函数
- 解决方案:手动定义构造函数并删除默认版本(如 ClassName() = delete )
4. 初始化列表 vs 构造函数体内赋值
方式 特点
初始化列表 - 在对象构造时直接初始化成员 - 必须用于引用/const成员初始化
构造函数体内赋值 - 实际上是先默认构造再赋值 - 对非基本类型有额外性能开销
class InitDemo
{
public:
// 推荐:初始化列表
InitDemo(int a, std::string s) : num(a), str(s) {}
// 不推荐:构造函数内赋值
InitDemo(int a) {
num = a; // 先执行string的默认构造,再赋值
str = "default";
}
private:
int num;
std::string str; // 类类型成员
};
5. 特殊构造函数
(1) 委托构造函数(C++11)
class Delegating
{
public:
// 主构造函数
Delegating(int a, double b) : x(a), y(b) {}
// 委托给主构造函数
Delegating() : Delegating(0, 0.0) {}
private:
int x;
double y;
};
(2) explicit 构造函数
- 禁止隐式类型转换
class ExplicitDemo
{
public:
explicit ExplicitDemo(int x) : val(x) {} // 必须显式调用
};
void demo()
{
// ExplicitDemo obj = 5; // 错误!禁止隐式转换
ExplicitDemo obj(5); // 正确
}
6. 构造函数的调用顺序
1. 基类构造函数(如果存在继承)
2. 成员变量的构造函数(按声明顺序)
3. 当前类的构造函数体
class Member
{
public:
Member() { std::cout << "Member构造\n"; }
};
class Base
{
public:
Base() { std::cout << "Base构造\n"; }
};
class Demo : public Base
{
public:
Demo() : m(), Base() {
std::cout << "Demo构造\n";
}
private:
Member m;
};
// 输出顺序:
// Base构造 → Member构造 → Demo构造
7. 实际应用建议
_优先使用初始化列表:尤其对类类型成员
_对单参数构造函数加 explicit :避免意外类型转换
_资源管理类遵循三五法则:如果需要自定义析构函数,通常也需要自定义拷贝构造和赋值运算符
_避免在构造函数中调用虚函数:此时虚函数机制未完全建立
class ResourceOwner
{
public:
explicit ResourceOwner(size_t size)
: data(new int[size]), size(size) {}
~ResourceOwner() { delete[] data; }
// 三五法则:需要自定义拷贝控制成员
ResourceOwner(const ResourceOwner&) = delete;
ResourceOwner& operator=(const ResourceOwner&) = delete;
private:
int* data;
size_t size;
};
二.析构函数
析构函数是 C++ 中用于对象销毁时自动调用的特殊成员函数,负责资源清理工作
1. 基本概念
- 作用:释放对象占用的资源(内存/文件/锁等)
- 特点:
- 函数名为 ~类名
- 无参数无返回值
- 不可重载(每个类只能有一个析构函数)
- 调用时机:
- 对象离开作用域时(栈对象)
- delete 动态对象时(堆对象)
- 容器销毁时(如 vector 析构会调用元素析构)
class FileHandler
{
public:
FileHandler()
{
file = fopen("data.txt", "r");
}
~FileHandler()
{
if(file) fclose(file); // 必须手动关闭文件
std::cout << "资源已释放\n";
}
private:
FILE* file;
};
2. 必须自定义析构函数的场景
// 场景1:动态内存管理
class MemoryPool
{
public:
MemoryPool(size_t size) { data = new int[size]; }
~MemoryPool() { delete[] data; } // 必须自定义
private:
int* data;
};
// 场景2:文件资源管理
class DatabaseConn
{
public:
~DatabaseConn() { disconnect(); } // 确保连接关闭
};
// 场景3:多态基类
class Base
{
public:
virtual ~Base() = default; // 虚析构函数!!!
};
class Derived : public Base
{
~Derived() override { /* 清理派生类资源 */ }
};
3. 默认析构函数的问题
问题1:浅拷贝导致双重释放
class ShallowCopy
{
public:
ShallowCopy(int size) { data = new int[size]; }
~ShallowCopy() { delete[] data; } // 危险!
private:
int* data;
};
void demo()
{
ShallowCopy obj1(10);
ShallowCopy obj2 = obj1; // 浅拷贝:两个对象共享data指针
// 析构时会导致同一内存被释放两次 → 程序崩溃
}
解决方案:实现拷贝控制(拷贝构造+赋值运算符)或禁用拷贝(C++11)
class SafeCopy
{
public:
// 方法1:禁用拷贝
SafeCopy(const SafeCopy&) = delete;
SafeCopy& operator=(const SafeCopy&) = delete;
// 方法2:实现深拷贝
SafeCopy(const SafeCopy& other)
{
data = new int[other.size];
std::copy(other.data, other.data+other.size, data);
}
};
问题2:部分资源泄漏
class ResourceLeak
{
public:
ResourceLeak()
{
res1 = new int[100];
res2 = new int[200];
}
~ResourceLeak() { delete[] res1; } // res2泄漏!
private:
int *res1, *res2;
};
解决方案:使用 RAII 对象管理资源(如 std::unique_ptr )
class SafeResource
{
std::unique_ptr<int[]> res1;
std::unique_ptr<int[]> res2;
public:
SafeResource() :
res1(std::make_unique<int[]>(100)),
res2(std::make_unique<int[]>(200)) {}
// 无需显式析构函数!
};
4. 析构函数调用顺序
1. 执行析构函数体:当前类的清理代码
2. 调用成员变量的析构函数(按声明逆序)
3. 调用基类析构函数(若存在继承,从派生类向基类析构)
class Member
{
public:
~Member() { std::cout << "Member析构\n"; }
};
class Base
{
public:
virtual ~Base() { std::cout << "Base析构\n"; }
};
class Derived : public Base
{
public:
~Derived() override
{
std::cout << "Derived析构\n";
}
private:
Member m;
};
// 调用示例:
Base* obj = new Derived();
delete obj;
输出顺序:
Derived析构 → Member析构 → Base析构
5. 最佳实践
1. RAII原则:资源获取即初始化,通过对象生命周期管理资源
2. 三五法则:若自定义析构函数,通常需要同时处理拷贝/移动操作
3. 多态基类声明虚析构函数:防止通过基类指针删除派生类对象时资源泄漏
4. 优先使用智能指针:避免手动内存管理错误
// 现代C++推荐写法
class ModernExample
{
std::unique_ptr<int[]> data; // 自动管理内存
std::mutex mtx; // RAII管理锁
public:
ModernExample() : data(std::make_unique<int[]>(100)) {}
// 无需显式析构函数!
};
关键总结
- 必须自定义析构函数:当类管理动态分配的资源或需要确保资源释放时
- 危险陷阱:默认浅拷贝会导致双重释放,需通过深拷贝或禁用拷贝避免
- 多态必备:基类必须声明虚析构函数,否则通过基类指针删除派生类对象会导致派生类资源泄漏
- 现代替代方案:优先使用智能指针和STL容器替代裸指针/手动资源管理
三.拷贝构造函数
拷贝构造函数是C++中的一种特殊构造函数,用于创建一个新对象作为现有对象的副本。
基本语法
class MyClass
{
public:
// 拷贝构造函数
MyClass(const MyClass& other)
{
// 复制other的成员到当前对象
}
};
特点
1. 参数是对同类型对象的const引用
2. 通常不应修改源对象,因此参数通常是const
3. 如果没有显式定义,编译器会自动生成一个默认的拷贝构造函数
使用场景
拷贝构造函数在以下情况下被调用:
1. 用一个对象初始化另一个对象时:
MyClass obj1;
MyClass obj2 = obj1; // 调用拷贝构造函数
MyClass obj3(obj1); // 调用拷贝构造函数
2. 对象作为函数参数按值传递时:
void func(MyClass obj);
MyClass original;
func(original); // 调用拷贝构造函数
3. 函数返回对象时(可能被编译器优化):
MyClass createObject()
{
MyClass obj;
return obj; // 可能调用拷贝构造函数
}
深拷贝与浅拷贝
1. 浅拷贝:仅复制指针值,不复制指针指向的内容(默认拷贝构造函数的行为)
2. 深拷贝:复制指针指向的内容,需要自定义拷贝构造函数
class DeepCopyExample
{
int* data;
public:
// 深拷贝构造函数
DeepCopyExample(const DeepCopyExample& other)
{
data = new int(*other.data); // 分配新内存并复制值
}
};
禁用拷贝
可以通过将拷贝构造函数声明为delete来禁止拷贝:
class NonCopyable
{
public:
NonCopyable(const NonCopyable&) = delete;
};
最佳实践
1. 对于包含动态分配资源的类,应实现自定义拷贝构造函数
2. 对于不应被拷贝的类,应显式禁用拷贝构造函数
3. 考虑使用移动语义(C++11引入)来提高性能
四.赋值运算符重载 (Copy Assignment Operator)
赋值运算符重载是C++中允许类自定义对象间赋值行为的特性,通常与拷贝构造函数一起使用。
基本语法
class MyClass
{
public:
// 赋值运算符重载
MyClass& operator=(const MyClass& other) {
if (this != &other)
{ // 防止自赋值
// 复制other的成员到当前对象
}
return *this; // 支持链式赋值
}
};
特点
1. 必须是成员函数,不能是友元函数
2. 通常返回当前对象的引用以支持链式赋值
3. 参数是对同类型对象的const引用
4. 需要处理自赋值情况
使用场景
当对象被赋值时自动调用:
MyClass obj1, obj2;
obj1 = obj2; // 调用赋值运算符重载
拷贝构造函数与拷贝赋值运算符的区别
拷贝构造函数和拷贝赋值运算符虽然都用于对象拷贝,但在本质上有重要区别:
1. 根本目的不同
- 拷贝构造函数:用于在创建新对象时,用已有对象初始化它。这是对象的"出生"过程。
- 拷贝赋值运算符:用于两个已存在对象之间的赋值操作。这是对象的"改变"过程。
2. 调用时机不同
拷贝构造函数在以下情况调用:
MyClass obj1; // 默认构造
MyClass obj2(obj1); // 直接调用拷贝构造
MyClass obj3 = obj1; // 这也是调用拷贝构造
MyClass func(MyClass o); // 参数传递时可能调用拷贝构造
拷贝赋值运算符在以下情况调用:
MyClass obj1, obj2; // 默认构造
obj1 = obj2; // 调用赋值运算符
3. 对象生命周期不同
- 拷贝构造:目标对象尚未存在,需要在构造过程中初始化
- 拷贝赋值:目标对象已经存在,需要先清理原有资源再赋新值
4. 实现要点不同
拷贝构造的实现:
MyClass(const MyClass& other)
{
// 只需关心从other复制到新对象
data = new int(*other.data); // 深拷贝示例
}
拷贝赋值的实现:
MyClass& operator=(const MyClass& other)
{
if(this != &other)
{ // 1. 检查自赋值
delete data; // 2. 释放原有资源
data = new int(*other.data); // 3. 深拷贝
}
return *this; // 4. 返回引用
}
5. 资源管理差异
- 拷贝构造:只需分配新资源并复制
- 拷贝赋值:需要先释放旧资源,再分配新资源,还要处理自赋值情况
6. 返回值不同
- 拷贝构造:没有返回值
- 拷贝赋值:通常返回对象引用以支持链式赋值(a = b = c)
实际应用建议
1. 遵循"三大法则":如果实现了其中任何一个(拷贝构造、拷贝赋值或析构),通常需要实现全部三个
2. 对于资源管理类,必须同时正确实现两者
3. 现代C++中可考虑使用"复制交换惯用法"简化实现
4. 不需要拷贝时应显式禁用(=delete)
深拷贝实现示例
class DeepCopyExample
{
int* data;
public:
// 赋值运算符重载
DeepCopyExample& operator=(const DeepCopyExample& other)
{
if (this != &other)
{
delete data; // 释放原有资源
data = new int(*other.data); // 分配新内存并复制
}
return *this;
}
};
复制交换惯用法 (Copy-and-Swap Idiom)
更安全和高效的实现方式:
class MyClass
{
// ... 其他成员 ...
public:
friend void swap(MyClass& first, MyClass& second) noexcept
{
// 交换所有成员
using std::swap;
swap(first.data, second.data);
}
MyClass& operator=(MyClass other) noexcept
{
swap(*this, other); // 交换当前对象与参数
return *this; // other离开作用域时会自动清理旧资源
}
};
禁用赋值
可以通过声明为delete来禁止赋值:
class NonAssignable
{
public:
NonAssignable& operator=(const NonAssignable&) = delete;
};
五.const成员函数
const成员函数是C++中保证函数不会修改对象状态的重要机制,它在类设计中扮演着关键角色。
基本概念
定义方式
在成员函数声明和定义的参数列表后添加 const 关键字:
class MyClass
{
public:
// 声明const成员函数
void display() const;
int getValue() const
{
return value; // 直接定义的const成员函数
}
private:
int value;
};
// 类外定义const成员函数
void MyClass::display() const
{
// 函数实现
}
核心特性
1. 不可修改性:不能修改类的非mutable成员变量
2. 调用权限:可以被const和非const对象调用
3. 重载机制:可以与同名非const成员函数形成重载
使用场景
1. 访问器方法(Getters)
class Student
{
std::string name;
public:
// const成员函数作为getter
const std::string& getName() const
{
return name;
}
};
2. 不修改对象状态的工具函数
class Matrix
{
double data[10][10];
public:
// 计算行列式但不修改矩阵内容
double determinant() const;
};
3. const对象接口
const Student s("Alice");
s.getName(); // 只能调用const成员函数
重要规则
1. 修改限制
class Counter
{
int count;
mutable int accessCount; // mutable例外
public:
void increment() const
{
// count++; // 错误!不能修改非mutable成员
accessCount++; // 正确:mutable成员可修改
}
};
2. 重载决议
class TextBlock
{
std::string text;
public:
// const版本
const char& operator[](size_t pos) const
{
return text[pos];
}
// 非const版本
char& operator[](size_t pos)
{
return text[pos];
}
};
const TextBlock ctb("Hello");
TextBlock tb("World");
ctb[0]; // 调用const版本
tb[0]; // 调用非const版本
高级用法
1. 逻辑常量性
class CachedData
{
mutable std::string cachedValue;
bool cacheValid;
public:
std::string getValue() const
{
if (!cacheValid)
{
// 虽然修改了成员,但不影响逻辑常量性
cachedValue = computeValue();
cacheValid = true;
}
return cachedValue;
}
};
2. 返回类型优化
class BigData
{
std::vector<int> data;
public:
// 返回const引用避免拷贝
const std::vector<int>& getData() const
{
return data;
}
};
最佳实践
1. 80%原则:80%的成员函数应该声明为const
2. const一致:相关函数应提供const和非const版本
3. 避免cast:不要用const_cast去掉const性质
4. mutable慎用:只在真正不影响逻辑状态时使用
5. 文档说明:对mutable成员的使用添加注释说明
C++中的const成员
const成员是指被 const 关键字修饰的类成员,包括const成员变量和const成员函数。
一、const成员变量
1. 特点
- 必须在构造函数的初始化列表中初始化
- 初始化后值不可修改
- 每个对象的const成员可以有不同的值
2. 声明与初始化
cpp
class MyClass
{
public:
const int size; // const成员变量声明
// 必须在初始化列表中初始化
MyClass(int s) : size(s) {}
// 错误!不能在构造函数体内赋值
// MyClass(int s) { size = s; }
};
3. 使用场景
- 类中需要保持不变的配置参数
- 对象特有的常量值
- 防止意外修改的重要成员
二、const成员函数
1. 特点
- 在函数声明和定义后加 const 关键字
- 不能修改类的任何非mutable成员变量
- 可以访问但不能修改对象状态
- 可以被const和非const对象调用
2. 语法
cpp
class MyClass
{
int value;
public:
// const成员函数
int getValue() const
{
return value; // 可以读取但不能修改成员
}
// 错误!const成员函数不能修改成员
// void setValue(int v) const { value = v; }
};
3. 使用场景
- 不修改对象状态的getter方法
- 保证线程安全的成员函数
- 需要被const对象调用的方法
三、const对象
1. 特点
- 声明为const的对象
- 只能调用const成员函数
- 所有成员变量被视为const
cpp
const MyClass obj(10);
int x = obj.getValue(); // 正确
// obj.setValue(20); // 错误!const对象不能调用非const方法
四、mutable成员
1. 特点
- 用 mutable 关键字修饰的成员变量
- 可以在const成员函数中被修改
- 通常用于不影响对象逻辑状态的成员
2. 示例
cpp
class MyClass
{
mutable int cache; // mutable成员
int value;
public:
int getValue() const
{
cache++; // 可以修改mutable成员
return value;
}
};
五、最佳实践
1. 尽可能将不修改对象状态的成员函数声明为const
2. const成员变量应在初始化列表中初始化
3. 对于需要频繁修改的缓存或计数器使用mutable
4. 设计类时应考虑const正确性
5. const成员函数可以重载非const版本
六.取地址及const取地址操作符重载
在C++中,我们可以重载取地址运算符( operator& )来定制对象地址获取行为,这在某些特殊场景下非常有用。
基本语法
普通取地址运算符重载
class MyClass
{
public:
MyClass* operator&()
{
return this; // 默认行为,通常不需要重载
// 可以返回其他指针,但需谨慎
}
};
const版本取地址运算符重载
class MyClass
{
public:
const MyClass* operator&() const
{
return this; // const对象的取地址
}
};
使用场景
1. 禁止获取真实地址(封装实现)
class NoAddress
{
private:
static int dummy;
public:
int* operator&() { return &dummy; } // 返回假地址
const int* operator&() const
{
return &dummy;
}
};
int NoAddress::dummy = 0;
2. 智能指针模拟
template<typename T>
class PtrWrapper
{
T* ptr;
public:
PtrWrapper(T* p) : ptr(p) {}
T* operator&() { return ptr; }
const T* operator&() const { return ptr; }
};
3. 代理模式
class AddressProxy
{
int* realTarget;
public:
AddressProxy(int* target) : realTarget(target) {}
int** operator&() { return &realTarget; } // 返回指针的地址
const int* const* operator&() const
{ return &realTarget; }
};
重要注意事项
1. 谨慎重载:除非有充分理由,否则不要重载取地址运算符
2. 保持一致性:const和非const版本应保持逻辑一致
3. 避免混淆:重载行为应与常规预期相符,避免造成困惑
4. STL兼容性:某些STL实现可能依赖标准取地址行为
实际应用示例
安全指针包装器
class SafePointer
{
void* ptr;
public:
SafePointer(void* p) : ptr(p) {}
// 普通版本
void** operator&()
{
static int guard;
if(!ptr) return reinterpret_cast<void**>(&guard);
return &ptr;
}
// const版本
const void* const* operator&() const
{
return const_cast<const void* const*>(&ptr);
}
};
最佳实践
1. 仅在特殊需求时重载取地址运算符
2. 确保重载后的行为有明确文档说明
3. 考虑提供 addressof() 成员函数作为替代方案
4. 保持const和非const版本的逻辑一致性
5. 注意线程安全性问题
相关文章:
类的六个默认成员函数
如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认…...
精益数据分析(21/126):剖析创业增长引擎与精益画布指标
精益数据分析(21/126):剖析创业增长引擎与精益画布指标 大家好!在创业和数据分析的探索道路上,我一直希望能和大家携手共进,共同学习。今天,我们继续深入研读《精益数据分析》,剖析…...
SAIL-RK3588协作机器人运动控制器技术方案
一、核心能力与政策适配 政策合规性 满足工信部《智能机器人重点技术攻关指南》要求,支持 EtherCAT主站协议(符合IEC 61158标准),助力企业申报工业机器人研发专项补贴(最高300万元/项目)核心板…...
手搓箱图并输出异常值(MATLAB)
看下需求 想要复刻这种箱图,咱们直接开始手搓 %% 可修改 % 生成模拟数据(假设5个用户群体的发帖数) data {randn(100,1)*10 30, ... % 核心用户randn(200,1)*5 10, ... % 边缘用户randn(150,1)*8 20, ... % 积极社交用户randn(8…...
Java:XML被自动转义
在Java中处理XML响应被自动转义的问题时,需结合XML规范及工具特性进行针对性处理。以下是常见原因及解决方案的总结: 一、XML自动转义的原因 字符安全性处理 XML中的保留字符(如 <、>、&)会被自动转义为实体&a…...
Day-3 应急响应实战
应急响应实战一:Web入侵与数据泄露分析 1. Web入侵核心原理 漏洞利用路径 未授权访问:弱口令(如空密码/默认口令)、目录遍历漏洞代码注入攻击:JSP/ASP木马、PHP一句话木马(利用eval($_POST[cmd])&…...
【软件设计师】模拟题一
以下是 10道软考-软件设计师模拟试题,涵盖高频考点和易错点,附带答案和解析: 一、软件工程 1. 在软件开发生命周期中,瀑布模型的主要特点是( ) A. 强调快速原型迭代 B. 阶段间有明…...
每日一练(4~24):互质的数【省模拟赛】
算法:暴力枚举 问题描述 如果两个整数 a, b 除了 1 以外,没有其它的公约数,则称整数 a 与 b 互质。 请问,与 2024 互质的数(包括 1)中,第 2024 小的是多少? 答案提交 这是一道结…...
金融软件测试有哪些注意事项?专业第三方软件测试服务机构分享
在现代金融行业中,软件系统的稳定性和安全性直接关系到资金的安全和业务的正常运转。金融软件因涉及庞大的资金流和敏感的个人及交易信息,对软件测试提出了更高的要求,那么金融软件在进行测试时有哪些注意事项呢?卓码软件测评作为专业的第三…...
关于QT信号、槽、槽函数的讲解
也是好久没有发帖子了,最近博主主要还是在边学QT边完成任务,所以进度很慢,但确实在这几天对于QT自身槽和信号这类特殊的机制有了一定简单的理解,所以还是想记录下来,如果有初学者看到帖子对他有一定的帮助,…...
算法训练营第三十天 | 动态规划 (三)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、01背包问题理论基础(一)动态规划五部曲确定dp数组以及下标的含义确定递推公式初始化dp数组确定遍历顺序 二、01背包问题理论基础&#…...
Vue开发网站会有“#”原因是前端路由使用了 Hash 模式
前言 网站链接中出现 #(井号)是因为你的前端路由使用了 Hash 模式(hash mode),这是一种前端框架(如 Vue.js、React 等)中常用的路由策略。 为什么有 # 比如 https://www.zimeinew.com/#/order…...
SpringBootTest报错
Unable to find a SpringBootConfiguration, you need to use ContextConfiguration or … 解决方案:在SpringTest注解中添加属性(classes )填写启动类 如我的启动类是MainApplication.class javax.websocket.server.ServerContainer no…...
【质量管理】现代TRIZ(萃智)理论概述
一、什么是TRIZ理论 TRIZ理论,即发明问题解决理论(Teoriya Resheniya Izobreatatelskikh Zadatch),是由前苏联发明家根里奇阿奇舒勒(Genrich S. Altshuller)于1946年创立的。它是一门基于知识的、面向人的发明问题解决系统化方法学。TRIZ理论通过研究大量的专利,总结出技…...
前端面经-JS篇(四)--回调地狱、promise异步编程、Proxy 与 Reflect 、模块化
一、回调地狱 回调地狱(Callback Hell),也称为回调地狱,是指在 JavaScript 中处理多个嵌套的异步回调函数时,代码结构变得非常难以阅读和维护的现象。 为什么会出现回调地狱? 回调地狱通常出现在需要执行…...
【oql】spark thriftserver内存溢出,使用oql查询导致oom的sql
eclipse memory analyzer (mat)软件内的OQL实现查询内促信息。 帮助信息:软件Help/Help Contents/Querying Heap Objects (OQL) 就是查询SparkExecuteStatementOperation 的statement 字段。 select objects s.statement from org.apache.spark.sql.hive.thriftser…...
算法设计与分析(基础)
问题列表 一、 算法的定义与特征,算法设计的基本步骤二、 算法分析的目的是什么?如何评价算法,如何度量算法的复杂性?三、 递归算法、分治法、贪婪法、动态规划法、回溯法的基本思想方法。四、 同一个问题,如TSP&#…...
爬虫学习——使用HTTP服务代理、redis使用、通过Scrapy实现分布式爬取
一、使用HTTP服务代理 由于网络环境、网站对用户的访问速度的限制等原因,使得爬取过程会出现IP被封禁,故使用代理可提高爬取速度。在Scrapy中提供了一个HttpProxyMiddleware专门用于进行爬虫代理设置。在使用该代理进行爬取操作时,需要先在ba…...
机器学习中的特征存储是什么?我需要一个吗?
本质上,特征存储是一个专用存储库,用于系统地存储和排列特征,主要用于数据科学家训练模型,并帮助已训练模型的应用程序进行预测。它是一个关键的聚合点,人们可以在此构建或修改从各种数据源提取的特征集合。此外,它还支持从这些特征组中创建和增强新的数据集,以满足处于…...
【C语言】C语言中的联合体与枚举类型
前言 在C语言中,联合体(union)和枚举(enum)是两种非常实用但又常被忽视的自定义数据类型。它们在内存管理、代码可读性以及程序设计的灵活性方面都有着独特的优势。今天,我们就来深入探讨一下联合体和枚举…...
Golang编程拒绝类型不安全
button-chen/containertypesafe-go: 使用泛型包装标准库的容器 list、ring、heap、sync.Pool 和 sync.Map,实现类型安全 简介 在 Go 中,标准库提供了多种容器类型,如 list、ring、heap、sync.Pool 和 sync.Map。然而,这些容器默认…...
炼锌废渣提取钴工艺流程
炼锌废渣中提取钴的工艺流程通常结合湿法冶金技术,针对废渣中钴与锌、铁、铜等金属的复杂共生特性,通过预处理、浸出、除杂、钴富集及提纯等步骤实现钴的高效回收。以下是典型工艺流程的详细说明: 一、预处理 炼锌废渣(如锌浸出…...
Restful接口学习
一、为什么RESTful接口是数据开发的核心枢纽? 在数据驱动的时代,RESTful接口如同数据高速公路上的收费站,承担着数据交换的核心职责。数据工程师每天需要面对: 异构系统间的数据交互(Hadoop集群 ↔ 业务系统…...
仿真每日一练 | ABAQUS应力松弛
应力松弛是弹性材料在应力作用下产生微塑性变形,并且逐渐积累,在保持应变或者位移不变的前提下,表现为应力逐渐下降的现象。今天介绍一个ABAQUS中应力松弛的相关案例,模型如下所示: 图1 模型认识 回顾一下ABAQUS的有限…...
智能电网第4期 | 电力设备全连接组网方案:从有线到无线无缝融合
随着新型电力系统建设的加速推进,电力设备通信网络正面临前所未有的挑战与机遇。在变电站自动化、输电线路监测、配电房智能化等场景中,传统通信方案已难以满足日益增长的连接需求: 环境复杂性:变电站强电磁干扰环境下需保障微秒级…...
Python 面向对象练习
不多bb了,直接上代码吧。 from pprint import pprint class Course:total_course []def __init__(self,name,id):self.name nameself.id idself.is_select FalseCourse.total_course.append(self)def __repr__(self):return (f"{__class__.__name__}("f"学…...
无感字符编码原址转换术——系统内存(Mermaid文本图表版/DeepSeek)
安全便捷无依赖,不学就会无感觉。 笔记模板由python脚本于2025-04-24 20:00:05创建,本篇笔记适合正在研究字符串编码制式的coder翻阅。 学习的细节是欢悦的历程 博客的核心价值:在于输出思考与经验,而不仅仅是知识的简单复述。 P…...
机器学习--线性回归模型
阅读本文之前,可以读一读下面这篇文章:终于有人把线性回归讲明白了 0、引言 线性回归作为统计学与机器学习的入门算法,以其简洁优雅的数学表达和直观的可解释性,在数据分析领域占据重要地位。这个诞生于19世纪的经典算法…...
HTML应用指南:利用GET请求获取微博签到位置信息
在当今数字化时代,社交媒体平台已成为人们日常生活中不可或缺的一部分。作为中国最受欢迎的社交平台之一,微博不仅为用户提供了一个分享信息、表达观点的空间,还通过其丰富的功能如签到服务,让用户能够记录自己生活中的点点滴滴。…...
如何检测Python项目哪些依赖库没有使用
要检测Python项目中哪些依赖库未被使用,可以采用以下方法: 1. 使用静态分析工具 vulture:静态分析工具,检测未使用的代码和导入 pip install vulture vulture your_project/pyflakes:检查未使用的导入语句 pip ins…...
数据仓库建设全解析!
目录 一、数据仓库建设的重要性 1. 整合企业数据资源 2. 支持企业决策制定 3. 提升企业竞争力 二、数据仓库建设的前期准备 1. 明确业务需求 2. 评估数据源 3. 制定项目计划 三、数据仓库建设的具体流程 1.需求分析 2.架构设计 3.数据建模 4.ETL 开发 5.…...
magic-api连接达梦数据库
引入依赖 然后手写驱动 <dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId><version>8.1.1.193</version></dependency> jdbc:dm://127.0.0.1:5236?schemaSALES...
向量检索新选择:FastGPT + OceanBase,快速构建RAG
随着人工智能的快速发展,RAG(Retrieval-Augmented Generation,检索增强生成)技术日益受到关注。向量数据库作为 RAG 系统的核心基础设施,堪称 RAG 的“记忆中枢”,其性能直接关系到大模型生成内容的精准度与…...
WHAT - 区分 Git PR 和 MR
文章目录 PR(Pull Request)MR(Merge Request)相同点总结 git pr 和 git mr 本质上都是「合并请求」的意思,但它们对应的是不同的平台术语。 PR(Pull Request) 平台:GitHub、Bitbuc…...
Axure复选框组件的深度定制:实现自定义大小、颜色与全选功能
在产品设计中,复选框作为用户与界面交互的重要元素,其灵活性直接影响到用户体验。本文将介绍如何利用Axure RP工具,通过高级技巧实现复选框组件的自定义大小、颜色调整,以及全选功能的集成,为产品原型设计增添更多可能…...
Datawhale AI春训营——用AI帮助老人点餐
详细内容见官网链接:用AI帮助老人点餐-活动详情 | Datawhale...
两段文本比对,高亮出差异部分
用法一:computed <div class"card" v-if"showFlag"><div class"info">*红色背景为已删除内容,绿色背景为新增内容</div><el-form-item label"与上季度比对:"><div class"comp…...
uniapp 仿小红书轮播图效果
通过对小红书的轮播图分析,可得出以下总结: 1.单张图片时容器根据图片像素定高 2.多图时轮播图容器高度以首图为锚点 3.比首图长则固高左右留白 4.比首图短则固宽上下留白 代码如下: <template><view> <!--轮播--><s…...
审计效率升级!快速匹配Excel报表项目对应的Word附注序号
财务审计报告一般包括:封面、报告正文、财务报表(Excel工作簿)以及对应的财务报表附注(Word文档)、事务所营业执照以及注册会计师证件。 在审计报告出具阶段,为各报表项目填充对应的Word附注序号ÿ…...
Python 中 `r` 前缀:字符串处理的“防转义利器”
# Python 中 r 前缀:字符串处理的“防转义利器” 在 Python 编程过程中,处理字符串时经常会遇到反斜杠 \ 带来的转义问题,而 r 前缀的出现有效解决了这一困扰。它不仅能处理反斜杠的转义,还在多种场景下发挥着重要作用。接下来&a…...
1️⃣6️⃣three.js_光源
16、光源 3D虚拟工厂在线体验 在 Three.js 中,环境光(AmbientLight)、点光源(PointLight)、平行光(DirectionalLight)、 聚光灯(SpotLight)、半球光(Hemisph…...
AD16如何执行DRC检测
AD16如何执行DRC检测 DRC检测主要用来查看走线是否出现通断,以及是否出现短路。 1)、点击“Tools”---“Design Rule Check…” 2)、全部勾选 3)、勾选“Electrical”中的“Batch”选项,参与DRC检测 4)、勾选“Routing”中的“Batch”选项,…...
PostgreSQL性能优化实用技巧
PostgreSQL的性能优化需从索引设计、查询调优、参数配置、硬件资源等多维度入手。以下为实战中验证有效的优化策略,适用于高并发、大数据量等场 一、索引优化:精准加速查询 1.选择正确的索引类型 BRIN索引:对按时间或数值顺…...
Vue3 ref与props
ref 属性 与 props 一、核心概念对比 特性ref (标签属性)props作用对象DOM 元素/组件实例组件间数据传递数据流向父组件访问子组件/DOM父组件 → 子组件响应性直接操作对象单向数据流(只读)使用场景获取 DOM/调用子组件方法组件参数传递Vue3 变化不再自…...
SpringBoot | 构建客户树及其关联关系的设计思路和实践Demo
关注:CodingTechWork 引言 在企业级应用中,客户关系管理(CRM)是核心功能之一。客户树是一种用于表示客户之间层级关系的结构,例如企业客户与子公司、经销商与下级经销商等。本文将详细介绍如何设计客户树及其关联关系…...
SpringCloud——负载均衡
一.负载均衡 1.问题提出 上一篇文章写了服务注册和服务发现的相关内容。这里再提出一个新问题,如果我给一个服务开了多个端口,这几个端口都可以访问服务。 例如,在上一篇文章的基础上,我又新开了9091和9092端口,现在…...
Springboot3+ JDK21 升级踩坑指南
目录 GetMapping和 RequestBody 一起使用时,会把请求方式由GET变为POST 变更默认的httpClient feign 超时配置失效 GetMapping和 RequestBody 一起使用时,会把请求方式由GET变为POST 变更默认的httpClient 添加依赖 <dependency><groupId&g…...
Qt UDP组播实现与调试指南
在Qt中使用UDP组播(Multicast)可以实现高效的一对多网络通信。以下是关键步骤和示例代码: 一、UDP组播核心机制 组播地址:使用D类地址(224.0.0.0 - 239.255.255.255)TTL设置:控制数据包传播范围(默认1,同一网段)网络接口:指定发送/接收的物理接口二、发送端实现 /…...
idea连接远程服务器kafka
一、idea插件安装 首先idea插件市场搜索“kafka”进行插件安装 二、kafka链接配置 1、检查服务器kafka配置 配置链接前需要保证远程服务器的kafka配置里边有配置好服务器IP,以及开放好kafka端口9092(如果有修改 过端口的开放对应端口就好) …...
第十节:性能优化高频题-虚拟DOM与Diff算法优化
优化策略:同层比较、静态节点标记、最长递增子序列算法 Key的作用:精确识别节点身份 虚拟DOM与Diff算法深度优化策略解析 一、核心优化策略 同层比较机制 Diff算法仅对比同一层级的虚拟节点,避免跨层级遍历带来的性能损耗。 • 实现原理&am…...