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

类A含私有构造/析构、B为友元类时,B中创建A的vector报错求助

解决C++中私有析构函数导致vector无法操作对象的问题

咱们先搞清楚为啥会出现这个error C2248的错误:

当你在B::addA里调用vecA.push_back(a)时,std::vector<A>内部会做这些操作:

  • 如果当前vector的容量不够装新元素,会开辟一块更大的内存
  • 把旧内存里的A对象拷贝/移动到新内存
  • 销毁旧内存里的A对象(这时候必须调用A的析构函数)
  • 把新的A对象拷贝到vector的内存里

但你把A的析构函数设成了私有,而std::vector<A>并不是A的友元类,它没权限调用A的私有析构函数,自然就编译失败了。

下面给你两个可行的解决方案,你可以根据自己的封装需求来选:

方案一:让std::vector成为A的友元

这是改动最小的方法,直接在A的类里加一行友元声明,允许vector访问A的私有成员:

修改后的A类代码:

class A {
private:
    A();
    A(const std::string& name, const float& num);
    ~A();
public:
    friend class B;
    friend class std::vector<A>; // 新增:允许vector访问A的私有成员
private:
    std::string name_;
    float num_;
};

优点:不需要改其他代码,一键解决问题。
缺点:会破坏A的封装性——任何地方只要定义了std::vector<A>,都能创建、销毁A的对象,这可能违背了你原本只想让B类操作A的设计初衷。

方案二:用智能指针存储A的对象(推荐)

改用std::vector<std::unique_ptr<A>>来存储A的指针,而不是直接存A的实例。这样vector管理的是指针,销毁指针时不需要调用A的析构函数(智能指针会自动搞定),同时还能保持A的封装性,只有B能创建A的对象。

具体步骤如下:

  1. 修改B类的私有成员,换成智能指针的vector:
class B {
public:
    B();
    ~B();
    void addA(const std::string name, const float num);
private:
    std::vector<std::unique_ptr<A>> vecA; // 从vector<A>改成vector<unique_ptr<A>>
};
  1. 在A类里添加std::default_delete<A>作为友元(因为std::unique_ptr的默认删除器需要调用A的析构函数):
class A {
private:
    A();
    A(const std::string& name, const float& num);
    ~A();
public:
    friend class B;
    friend struct std::default_delete<A>; // 新增:允许默认删除器访问析构函数
private:
    std::string name_;
    float num_;
};
  1. 修改B的addA函数,用std::make_unique创建A的对象并加入vector:
void B::addA(const std::string name, const float num) {
    vecA.push_back(std::make_unique<A>(name, num));
}

如果你不想用std::make_unique,也可以直接用new创建对象(不过更推荐前者,更安全):

vecA.emplace_back(new A(name, num));

优点:

  • 完美保持A的封装性:只有B类能创建A的对象,其他地方根本没法实例化A
  • 避免了vector直接操作A的实例,减少了封装泄露的风险
  • 智能指针自动管理内存,不用手动释放A的对象,省心

缺点:需要修改B类的成员类型和添加友元声明,改动比方案一大,但更符合面向对象的设计原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:37:31