You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译器如何识别需构造新类实例?以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;
}

编译器的具体处理逻辑

  1. 明确目标类型:代码左侧已经显式声明变量test的类型为Mystring,编译器从一开始就清楚最终要构造一个Mystring实例。
  2. 匹配构造函数:右侧的"Hi there"是C字符串字面量,本质为const char*类型(你的构造函数参数是char*,能编译通过是因为编译器的兼容扩展,标准C中建议将构造函数参数改为const char*)。编译器会在Mystring的公开构造函数中,查找可接受该类型参数的构造函数——也就是你定义的Mystring(char *s)。
  3. 隐式转换与构造优化:编译器会利用找到的构造函数,把"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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 10:15:35