You need to enable JavaScript to run this app. C++类隐式转换场景下scopedptr对象的所属类型及调用权限问题
优惠活动
大模型
产品
解决方案
定价
更多

C++类隐式转换场景下scopedptr对象的所属类型及调用权限问题

#include <iostream>
using namespace std;

class temp
{
public:
    temp()
    {
        std::cout << "Constructor created." << std::endl;
    }
    ~temp()
    {
        std::cout << "Deconstructor called." << std::endl;
    }
};

class scopedptr
{
private:
    temp* ptr;
public:
    scopedptr(temp* p)
    {
        ptr = p;
        std::cout << "scoped" << std::endl;
    }
    ~scopedptr()
    {
        delete ptr;
    }
};

int main()
{
    {
        scopedptr a = new temp();
    }
}

问题1:对象a的类型归属

scopedptr a = new temp();中定义的a明确是scopedptr类的对象,和temp类没有直接的类型从属关系。

问题2:a可以调用的成员范围

a只能调用scopedptr类中定义的public成员,完全不能直接调用temp类的成员。如果要通过a访问内部持有的temp对象的成员,需要在scopedptr中额外重载*解引用运算符或者->成员访问运算符才可以,示例如下:

// 在scopedptr类中添加如下代码
temp* operator->() {
    return ptr;
}
temp& operator*() {
    return *ptr;
}

添加后就可以通过a->xxx或者(*a).xxx访问temp的公开成员了。

问题3:触发的隐式转换逻辑

这个语句能正常执行的核心原因是scopedptr的构造函数scopedptr(temp* p)没有加explicit修饰,属于允许隐式转换的构造函数,执行逻辑分三步:

  1. 先执行new temp(),在堆上创建一个temp类的对象,返回该对象的temp*类型指针
  2. 编译器发现赋值右侧是temp*类型,左侧需要scopedptr类型,自动触发隐式转换:用得到的temp*指针作为参数,调用scopedptr的单参数构造函数,生成一个临时的scopedptr对象
  3. 用这个临时的scopedptr对象拷贝构造得到对象a(C++17及以后版本会做复制消除,直接在a的内存空间构造对象,不会产生临时对象)

如果不想允许这种隐式转换,只需要给scopedptr的构造函数加上explicit修饰:explicit scopedptr(temp* p),这时原来的语句就会编译报错,必须写成scopedptr a(new temp());才可以正常编译。

内容的提问来源于stack exchange,提问作者aman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 20:06:08