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

如何仅允许指定类创建其他类实例?MyData与MyDataContainer场景探讨

解决方案分析

方案一:私有构造+友元类

这是你考虑的方案,完全可行:

  • 实现方式:将MyData的构造函数设为private,然后在MyData中声明MyDataContainer为友元类,让它拥有创建MyData实例的权限。
  • 示例代码:
class MyData {
private:
    MyData() {} // 私有构造,禁止外部直接创建
    friend class MyDataContainer; // 授权MyDataContainer访问
    // MyData的其他业务成员
};

class MyDataContainer {
private:
    MyData* data = nullptr;
public:
    MyData* getMyData() {
        if (!data) {
            data = new MyData(); // 懒实例化逻辑留在容器类中
        }
        return data;
    }
    // 其他对外暴露的外观方法
};
  • 优点:实现简单直接,精准满足“仅MyDataContainer能创建MyData”的需求,懒加载逻辑的位置也符合要求。
  • 缺点:友元关系会拉高两个类的耦合度,后续如果要新增其他类能创建MyData,必须修改MyData的代码添加新友元,违反开闭原则。

方案二:将MyData作为MyDataContainer的私有内部类

这是更贴合外观类定位的方案:

  • 实现方式:把MyData定义为MyDataContainer的私有嵌套类,外部代码完全无法直接访问MyData,彻底把实例创建权锁在容器内部。
  • 示例代码:
class MyDataContainer {
private:
    // 私有内部类,外部完全不可见
    class MyData {
    public:
        MyData() {}
        // MyData的业务方法
    };
    MyData* data = nullptr;
public:
    // 对外只暴露封装后的业务接口,无需直接返回MyData实例
    void doBusinessLogic() {
        if (!data) {
            data = new MyData(); // 懒实例化逻辑
        }
        // 调用MyData的方法完成业务操作
    }
};
  • 优点:封装性拉满,外部完全感知不到MyData的存在,完美契合外观类“隐藏内部细节”的职责;没有友元带来的耦合问题,后续修改MyData的实现不会影响外部代码。
  • 缺点:如果必须让外部获取MyData实例(比如外部需要直接调用MyData的方法),这个方案就不适用——但从你的需求来看,外观类本就该屏蔽内部实现,这反而算是优势。

方案三:简化版工厂模式

如果不想用友元或内部类,也可以让MyDataContainer兼任工厂角色:

  • 实现方式:将MyData的构造设为private,在MyData中写一个静态创建方法,通过友元授权给MyDataContainer调用,把创建逻辑封装起来。
  • 示例代码:
class MyData {
private:
    MyData() {}
    // 静态创建方法,仅授权给MyDataContainer调用
    static MyData* createInstance() {
        return new MyData();
    }
    friend class MyDataContainer;
public:
    // MyData的公共业务方法
};

class MyDataContainer {
private:
    MyData* data = nullptr;
public:
    MyData* getInstance() {
        if (!data) {
            data = MyData::createInstance(); // 懒加载
        }
        return data;
    }
};
  • 优点:把创建逻辑封装在MyData的静态方法中,比直接new更清晰,后续修改创建逻辑(比如改成对象池)不用改动Container的代码。
  • 缺点:本质还是依赖友元授权,耦合度问题和方案一一样,除非你后续要扩展多种MyData实现,否则属于过度设计。

总结建议

如果你的核心需求是隐藏MyData的存在,仅通过MyDataContainer对外提供服务,优先选方案二(私有内部类),封装性最好,完全符合外观类的设计初衷。

如果必须让外部能获取MyData实例(比如外部需要直接调用MyData的方法),那么**方案一(私有构造+友元)**足够简单直接,虽然有耦合,但在需求明确的情况下是合理选择。工厂模式在这里没必要,除非你有扩展多种MyData实现的规划。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:25:55