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

如何正确初始化含两个指针成员的C++类?直接实例化崩溃如何解决

问题根因与修复方案

所有崩溃和异常本质是野指针访问,你的代码存在以下核心错误:

  • 默认构造函数变量遮蔽(最直接原因):你在默认构造函数内部重新定义了和类成员同名的局部变量p_real、p_imaginar,堆内存分配给了局部变量,类本身的成员指针全程未初始化,是野指针。直接调用operator<<或getter时访问野指针指向的内存,直接触发崩溃。调用setter后类成员指针被赋值为有效地址,因此暂时不会崩溃。
  • 拷贝构造逻辑错误:拷贝构造函数执行时,类成员p_real、p_imaginar还未初始化,直接判断if (p_real != nullptr)完全无效,野指针判断结果不可预期,后续操作大概率触发内存错误。
  • 内存释放逻辑全错:析构函数、setter函数中都先执行p_real = nullptr再调用delete p_real,等于直接丢失原内存地址,既没有释放原有堆内存造成泄漏,delete空指针也完全没有实际作用。
  • 运算符重载语法错误:你已经把operator<<声明为友元全局函数,后续实现却写为类成员函数,语法不合法,编译阶段本就应该报错。
  • 对象声明语法错误:你的类名是numar_complex,声明对象时写的numar complex x多了空格,属于语法错误。

修正后的完整代码

#include <iostream>
class numar_complex {
    friend std::ostream& operator<<(std::ostream& out, const numar_complex& num);
    friend std::istream& operator>>(std::istream& is, numar_complex& num);

private:
    double* p_real;
    double* p_imaginar;

public:
    // 构造、析构
    numar_complex()
    {
        // 直接给类成员指针赋值,不要重新定义局部变量
        p_real = new double(0.0);
        p_imaginar = new double(0.0);
        std::cout << "constructor" << std::endl;
    }
    numar_complex(const numar_complex& nr)
    {
        // 拷贝构造不需要先释放,当前对象成员还未初始化,直接分配新内存即可
        p_real = new double(*nr.p_real);
        p_imaginar = new double(*nr.p_imaginar);
        std::cout << "copy constructor " << std::endl;
    }
    ~numar_complex()
    {
        // 先释放内存,再置空指针
        delete p_real;
        p_real = nullptr;
        delete p_imaginar;
        p_imaginar = nullptr;
        std::cout << "destructor" << std::endl;
    }

    // getter
    double get_p_real() const
    {
        return *p_real;
    }
    double get_p_imaginar() const
    {
        return *p_imaginar;
    }
    // setter
    void set_p_real(double x)
    {
        // 先释放原有内存,再分配新内存
        delete p_real;
        p_real = new double(x);
    }
    void set_p_imaginar(double x)
    {
        delete p_imaginar;
        p_imaginar = new double(x);
    }
};

// 友元运算符重载要放在类外面实现
std::ostream& operator<<(std::ostream& out, const numar_complex& num)
{
    if (*num.p_imaginar >= 0) {
        out << *num.p_real << "+" << *num.p_imaginar << "*i \n";
    } else {
        out << *num.p_real << *num.p_imaginar << "*i \n";
    }
    return out;
}

正确调用示例

int main() {
    numar_complex x; 
    std::cout << x; // 输出0+0*i,不会崩溃
    x.set_p_real(1); 
    x.set_p_imaginar(1); 
    std::cout << x; // 输出1+1*i
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:51:02