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

不使用嵌套类,如何仅允许类A创建类B的对象?

解决思路与实现代码

要实现只有类A能实例化类B(不使用嵌套类),核心是利用C++的友元机制结合访问控制,具体思路如下:

  • 将类B的构造函数设为private:这样除了B自身和被声明为友元的类/函数,其他任何外部代码都无法直接创建B的实例。
  • 在类B中声明类A为友元类:友元类拥有访问目标类所有私有/保护成员的权限,这样A就能自由调用B的私有构造函数来创建对象。

修改后的完整代码示例

#include <vector>
using namespace std;

class B {
    // 声明A为友元类,允许A访问B的私有成员
    friend class A;
private:
    // 将构造函数设为私有,禁止外部直接实例化
    B(int x1, int y1, int x2, int y2) 
        : x1(x1), y1(y1), x2(x2), y2(y2) {}
    
    int x1;
    int y1;
    int x2;
    int y2;
public:
    ~B() = default; // 析构函数保持public,方便容器自动销毁对象
    void updateCoordinates(int x1, int y1, int x2, int y2) {
        this->x1 = x1;
        this->y1 = y1;
        this->x2 = x2;
        this->y2 = y2;
    }
};

class A {
public:
    A(int mode);
    ~A() = default;
private:
    vector<B> bList;
};

A::A(int mode) {
    // 根据mode的值,自由创建B的对象并添加到bList
    if (mode == 1) {
        bList.emplace_back(10, 20, 30, 40);
        bList.emplace_back(50, 60, 70, 80);
    } else {
        bList.emplace_back(0, 0, 100, 100);
    }
}

关键点说明

  1. 私有构造函数:B的构造函数被设为private后,像B b(1,2,3,4);这样的外部代码会直接编译报错,彻底禁止外部实例化B。
  2. 友元声明:friend class A;让A获得了B的所有私有成员访问权,所以A的构造函数里可以用emplace_back直接构造B的对象(也可以用push_back(B(...)),但emplace_back更高效)。
  3. 析构函数与成员函数:B的析构函数保持public是合理的,因为vector在销毁元素时需要调用析构函数;updateCoordinates作为public成员,允许任何持有B对象的代码(包括A)修改坐标,符合你的需求。

补充:替代思路(若不想用友元)

如果担心友元破坏封装性,也可以尝试静态工厂方法:将B的构造函数设为private,在B中添加静态成员函数static B create(...),但这个方法最终还是需要把A设为友元(否则静态方法也得设为public,无法限制其他类调用)。所以友元仍是最直接且符合需求的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:51:11