如何限制函数返回的对象指针被复制/赋值,同时仍可访问对象内容?
实现方案
一、实现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
相关产品推荐
相关产品推荐

