Objective-C源码ExplicitInit类解析及使用报错排查
ExplicitInit模板类解析及测试代码错误修复
一、ExplicitInit模板类的含义
这个模板类是显式初始化容器,核心作用是手动控制对象的构造时机,是C++中placement new(定位new)用法的典型实践:
alignas(Type) uint8_t _storage[sizeof(Type)]:开辟一块与Type类型大小完全一致、对齐规则相同的原始内存空间,仅用于占位,此时内存中并未构造实际的Type对象。init(Ts &&... Args):通过placement new在预先分配的_storage内存上构造Type对象,借助std::forward实现参数的完美转发,让使用者可以灵活传递Type构造所需的任意参数,从而显式触发对象构造。get():将原始内存地址强制转换为Type*并返回引用,让使用者能够访问构造完成后的对象实例。
简单来说,它就是一个"对象占位器",允许先预留内存空间,在需要的时机再真正创建对象,常见于延迟初始化、内存池等场景。
二、测试代码的错误分析与修复
错误原因
测试代码存在两个明确问题:
- 类名拼写错误:模板类的正确名称是
ExplicitInit,但代码中误用了MyExplicitInit,编译器无法识别该类。 - 构造函数不匹配:
MyC仅定义了需要两个long参数的构造函数,调用e1.init()时未传递任何参数,init()内部尝试调用MyC的无参构造函数,而该构造函数不存在,导致编译失败。
修复后的测试代码
修复方案1:为MyC添加无参构造函数
class MyC{ public: long l1; long l2; // 添加无参构造函数 MyC() : l1(0), l2(0) {} MyC(long _l1, long _l2){ l1 = _l1; l2 = _l2; } }; int main(){ // 修正类名为正确的ExplicitInit ExplicitInit<MyC> e1 {}; // 调用无参init,触发MyC的无参构造 e1.init(); // 通过get()访问构造后的对象 auto& obj = e1.get(); return 0; }
修复方案2:调用init()时传入MyC构造所需参数
如果不想修改MyC的定义,直接传递构造参数即可:
class MyC{ public: long l1; long l2; MyC(long _l1, long _l2){ l1 = _l1; l2 = _l2; } }; int main(){ ExplicitInit<MyC> e1 {}; // 传入MyC构造需要的两个long类型参数 e1.init(100, 200); auto& obj = e1.get(); // 此时obj.l1=100,obj.l2=200 return 0; }
内容的提问来源于stack exchange,提问作者Crazs
相关产品推荐
相关产品推荐

