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

如何限制函数返回的对象指针被复制/赋值,同时仍可访问对象内容?

实现方案

一、实现getSomeClass()的指针限制(禁止复制/赋值,仅允许成员调用)

核心思路是返回自定义代理对象而非原生指针,通过限制代理类的拷贝行为、屏蔽到原生指针的转换,仅保留成员访问的能力。

代码实现

#include <utility>

// 前向声明目标类
class SomeClass;

// 自定义不可复制的指针代理类
class NonCopyableAccessPtr {
private:
    SomeClass* m_ptr;

    // 禁用拷贝构造与赋值
    NonCopyableAccessPtr(const NonCopyableAccessPtr&) = delete;
    NonCopyableAccessPtr& operator=(const NonCopyableAccessPtr&) = delete;

public:
    // 允许移动构造(可选,按需控制所有权转移)
    NonCopyableAccessPtr(NonCopyableAccessPtr&& other) noexcept : m_ptr(other.m_ptr) {
        other.m_ptr = nullptr;
    }

    NonCopyableAccessPtr& operator=(NonCopyableAccessPtr&& other) noexcept {
        if (this != &other) {
            m_ptr = other.m_ptr;
            other.m_ptr = nullptr;
        }
        return *this;
    }

    // 仅允许内部/友元创建实例
    explicit NonCopyableAccessPtr(SomeClass* ptr) : m_ptr(ptr) {}

    // 重载->,仅允许调用目标对象的public成员
    SomeClass* operator->() const {
        return m_ptr;
    }

    // 可选:禁用解引用操作,避免获取原生对象引用
    // SomeClass& operator*() const = delete;
};

// 目标类定义
class SomeClass {
public:
    void func() { /* 业务逻辑 */ }
    // 其他public成员...

    // 授权getSomeClass()创建代理对象
    friend NonCopyableAccessPtr getSomeClass();
};

// 返回代理对象而非原生指针
NonCopyableAccessPtr getSomeClass() {
    return NonCopyableAccessPtr(new SomeClass());
}

使用效果

// 合法:正常调用public成员
getSomeClass()->func();

// 非法:无法将代理对象赋值给原生指针(编译报错)
// SomeClass* ptr = getSomeClass();

// 非法:无法拷贝代理对象(编译报错,若开启移动则仅能转移所有权)
// auto ptr = getSomeClass();

二、实现assignSomeClass()的隐藏内容需求(可赋值但无法访问成员)

核心思路是返回指向不完整类型或空基类的指针,让用户无法通过指针访问目标类的任何成员。

方案1:不完整类型(Opaque Pointer)

// 仅前向声明,不暴露SomeClass的完整定义
class SomeClass;

// 返回void*或前向声明的类指针
void* assignSomeClass() {
    return new SomeClass();
}

方案2:空基类封装

// 公开的空基类
class HiddenObject {};

// 目标类继承自空基类
class SomeClass : public HiddenObject {
public:
    void func() { /* 业务逻辑 */ }
};

// 返回空基类指针
HiddenObject* assignSomeClass() {
    return new SomeClass();
}

使用效果

// 合法:正常存储指针
void* ptr1 = assignSomeClass();
HiddenObject* ptr2 = assignSomeClass();

// 非法:无法调用目标类成员(编译报错)
// ptr2->func();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:40:08