编译器如何识别需构造新类实例?以Mystring类初始化为例
关于C++中
Mystring test="Hi there";语法的编译器逻辑解析 你提到的Mystring test="Hi there";属于C++的拷贝初始化语法,编译器的处理逻辑可以拆解为以下几步:
代码场景回顾
你的简化版Mystring代码如下:
#include<iostream> #include<cstring> class Mystring { private: char * str; public: Mystring(char * s) :str{nullptr} { str = new char[std::strlen(s)+1]; std::strcpy(str,s); std::cout<<"constructor is called for: "<<this->str<<std::endl; } }; int main() { Mystring x{"ABC"}; Mystring test="Hi there"; return 0; }
编译器的具体处理逻辑
- 明确目标类型:代码左侧已经显式声明变量
test的类型为Mystring,编译器从一开始就清楚最终要构造一个Mystring实例。 - 匹配构造函数:右侧的
"Hi there"是C字符串字面量,本质为const char*类型(你的构造函数参数是char*,能编译通过是因为编译器的兼容扩展,标准C中建议将构造函数参数改为const char*)。编译器会在Mystring的公开构造函数中,查找可接受该类型参数的构造函数——也就是你定义的Mystring(char *s)。 - 隐式转换与构造优化:编译器会利用找到的构造函数,把
"Hi there"隐式转换为临时Mystring对象,再将临时对象拷贝给test。不过现代编译器会触发返回值优化(RVO),直接跳过临时对象的创建,在test的内存空间上直接执行构造逻辑,最终效果和Mystring x{"ABC"};的直接初始化完全一致。
关键前提:构造函数非explicit
这种隐式初始化能生效的核心是构造函数未被explicit关键字修饰。如果给构造函数加上explicit:
explicit Mystring(char * s) { ... }
那么Mystring test="Hi there";会直接编译报错——explicit的作用就是禁止这类隐式转换初始化,必须使用Mystring test("Hi there");或Mystring test{"Hi there"};这类显式构造的写法。
内容的提问来源于stack exchange,提问作者ANDREW
相关产品推荐
相关产品推荐

