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

在类构造函数中引用*this触发Write Access Violation错误的原因

解决构造函数中传递对象引用导致的Write Access Violation错误

问题根源分析

  1. 未初始化指针的非法解引用:B类的m_a是指针成员,在带参构造函数B(A &a)中直接执行*m_a = a时,m_a从未被赋值,指向随机内存地址。写入该地址会触发写入访问违规。
  2. 成员变量构造顺序问题:A类的m_b作为成员变量,会在A的构造函数体执行前先调用默认构造函数初始化,之后的m_b = B(*this)只是赋值操作,不仅低效,还没正确建立A和B的关联。

修复方案

步骤1:修正B类的构造逻辑

将B的构造函数改为通过初始化列表把指针指向传入的A对象地址,而非解引用未初始化的指针:

B::B(A &a) : m_a(&a) {
    // 无需额外赋值操作,指针已指向正确的A对象
}

如果希望用引用而非指针(更安全,避免空指针),可以修改B类的成员为A& m_a,构造函数同样用初始化列表初始化:

class B {
public:
    B(A &a);
    ~B();
private:
    A& m_a; // 改为引用成员
};

B::B(A &a) : m_a(a) {
}

注意:引用成员必须在初始化列表中初始化,因此B类不能有默认构造函数。

步骤2:修正A类的构造逻辑

A的构造函数直接用初始化列表构造m_b,跳过默认构造+赋值的冗余步骤,同时确保m_b在A对象构造过程中就正确关联当前对象:

A::A(int x) : m_b(*this) {
    // 构造函数体可添加其他初始化逻辑
}

如果保留A的默认构造函数,同样需要用初始化列表构造m_b:

A::A() : m_b(*this) {
}

完整修正代码

class A;

class B {
public:
    B(A &a);
    ~B();
private:
    A* m_a; // 或改为 A& m_a,对应上方的引用实现
};

class A {
public:
    A();
    A(int x);
    ~A();
private:
    B m_b;
};

B::B(A &a) : m_a(&a) {
}

B::~B() {}

A::A() : m_b(*this) {
}

A::A(int x) : m_b(*this) {
}

A::~A() {}

int main() {
    A temp = A(10);
}

额外注意事项

  • 在对象构造过程中传递this是合法的,但要确保被调用的函数(如B的构造函数)不会访问A中尚未初始化的成员——因为此时A的成员还未完成构造,访问未初始化的成员会导致未定义行为。
  • 若使用引用关联A和B,需保证A对象的生命周期长于B对象。在本场景中,B是A的成员,A的生命周期天然覆盖B,因此无需担心悬空引用问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:32:39