类相关
class和struct的异同?
相同点:
- 都可以包含成员变量(属性)和成员函数(方法)
- 都支持访问控制修饰符(
public、private、protected)- 都可以继承其他类 / 结构体,也可以被继承
- 都可以包含构造函数、析构函数
- 都可以实现多态、模板等 C++ 特性
- 都可以使用
friend声明外部函数或类不同点:
特性 structclass默认访问权限 成员默认是 public成员默认是 private默认继承方式 默认是 public继承默认是 private继承传统用途 主要用于存储数据(C 风格结构体的扩展) 主要用于实现面向对象的类(封装数据和操作) 模板参数 不能作为模板参数的关键字(C++11 前) 可以作为模板参数的关键字 使用建议:
- 当需要一个主要用于存储数据的简单结构时,使用
struct- 当需要实现封装性强、包含复杂逻辑的面向对象类时,使用
class- 保持代码风格一致性,避免混用造成混淆
实际上,
struct和class在 C++ 中本质上是相似的,只是默认行为不同,开发者可以根据需求灵活选择。
什么是C++仿函数
在 C++ 中,仿函数(Functor) 是一种重载了
operator()的类或结构体实例。它的行为类似函数,但可以像对象一样存储状态,因此也被称为函数对象(Function Object)。仿函数的特点:
- 兼具函数和对象的特性:可以像函数一样被调用,同时可以拥有成员变量和成员函数来保存状态
- 可定制性:通过不同的成员变量值,同一个仿函数类可以表现出不同的行为
- 适配性好:广泛用于 STL 算法中(如
sort、find_if等),作为自定义操作的参数仿函数 vs 普通函数:
- 仿函数可以携带状态(通过成员变量),普通函数不行
- 仿函数可以被模板特化,普通函数不行
- 仿函数的类型是明确的,可用于模板参数推导
- 在性能上,仿函数调用通常可以被编译器内联优化,效率可能高于函数指针
C++11 及以后,lambda 表达式提供了更简洁的匿名函数对象实现,但仿函数在需要复用或需要复杂状态管理的场景下仍然非常有用。
一般性问题
函数和函数指针的类型是什么,有什么决定
在 C++ 中,函数和函数指针都有明确的类型,其类型由函数的参数列表和返回值类型共同决定,与函数名或指针变量名无关。
1. 函数的类型
函数的类型由两部分决定:
- 参数列表(参数的类型、数量、顺序)
- 返回值类型
例如:
// 函数1:参数为int,返回值为int int add(int a, int b) { return a + b; } // 函数2:无参数,返回值为void void print() { cout << "hello" << endl; }
- 函数
add的类型是:int(int, int)(可理解为 “接受两个 int 参数,返回 int 的函数”)- 函数
void()(可理解为 “无参数,返回 void 的函数”)2. 函数指针的类型
函数指针是指向函数的指针变量,其类型与它所指向的函数的类型完全一致,同样由参数列表和返回值类型决定。
定义函数指针时,需要显式指定其指向的函数类型:
// 定义函数指针类型(与add函数类型匹配) int (*func_ptr1)(int, int); // 定义函数指针类型(与print函数类型匹配) void (*func_ptr2)();
func_ptr1的类型是:int(*)(int, int)(指向 “接受两个 int 参数,返回 int 的函数” 的指针)func_ptr2的类型是:void(*)()(指向 “无参数,返回 void 的函数” 的指针)3. 类型匹配规则
函数指针只能指向与其类型完全匹配的函数:
- 参数列表必须完全一致(类型、数量、顺序)
- 返回值类型必须完全一致
int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } double mul(double a, double b) { return a * b; } int main() { int (*calc)(int, int); // 函数指针类型:int(*)(int, int) calc = add; // 合法:类型匹配 calc = sub; // 合法:类型匹配 calc = mul; // 非法:参数和返回值类型不匹配(double vs int) return 0; }4. 简化函数指针类型的方法
复杂的函数指针类型可以通过
typedef或using(C++11)简化:// 方法1:typedef typedef int (*CalcFunc)(int, int); CalcFunc func1 = add; // 等价于 int(*func1)(int, int) = add; // 方法2:using(更直观) using PrintFunc = void(*)(); PrintFunc func2 = print; // 等价于 void(*func2)() = print;总结
- 函数的类型由参数列表和返回值类型共同决定。
- 函数指针的类型必须与它所指向的函数类型完全一致。
- 函数名本身不是类型,但可以隐式转换为对应函数指针类型的右值。
STL相关
在一个空的map中直接使用 map[key] = value; 会有问题吗
在 C++ 中,在一个空的
std::map中直接使用map[key] = value;语法是完全没有问题的。这是因为
std::map的operator[]操作符设计具有一个特殊的行为:当指定的键(key)在 map 中不存在时,它会自动插入一个新的键值对。具体来说:
首先,会在 map 中插入一个新元素,键为
key,值为该类型的默认构造值然后,返回对这个新插入值的引用
最后,通过赋值操作符
=将value赋给这个引用

被折叠的 条评论
为什么被折叠?



