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

指向Base::Inner类的匿名与命名内部派生类的指针行为差异

问题分析与解决:内部类指针访问异常

问题现象

在给定的C++代码中,Derived_GrandChild构造函数访问基类Base的两个指针时:

  • 指向匿名内部派生类实例的指针能正确输出test_int = 1
  • 指向命名内部派生类的指针输出未初始化的垃圾值(-858993460)

核心原因

两种指针的差异源于所指向对象的生命周期不同:

  • 匿名内部派生类实例anonymous_inner_derived:它是Derived类的成员变量,生命周期与Derived(或其派生类Derived_GrandChild)对象完全绑定。只要Derived对象存在,该实例就处于有效状态,因此指针访问正常。
  • 命名内部类Inner_Derived的局部实例inner_derived:它是Derived构造函数内的局部变量,构造函数执行完毕后,该局部变量会被销毁,对应的内存区域被释放或标记为可复用。此时inner_class_ptr_to_inner_derived_class成为悬空指针,后续通过它访问成员属于C++未定义行为,输出垃圾值是典型表现。

修复方案

要解决这个问题,需要让命名内部类的实例生命周期与Derived对象一致,以下是两种可行方式:

方案1:将实例改为类成员变量

直接把Inner_Derived的实例定义为Derived的成员变量,确保其生命周期与类对象绑定:

class Base {
public:
    class Inner {
    public:
        int test_int = 1;
    };

    Inner* inner_class_ptr_to_anonymous_inner_derived_class;
    Inner* inner_class_ptr_to_inner_derived_class;
};

class Derived : public Base {
public:
    class Inner_Derived : public Base::Inner {};
    Inner_Derived inner_derived; // 改为Derived的成员变量
    class : public Base::Inner {}anonymous_inner_derived;
    Derived()
    {
        inner_class_ptr_to_inner_derived_class = &inner_derived;
        inner_class_ptr_to_anonymous_inner_derived_class = &anonymous_inner_derived;
    }
};

class Derived_GrandChild : public Derived {
public:
    Derived_GrandChild() {  
        std::cout << "Anonymous Inner Derived Class test_int = " << inner_class_ptr_to_anonymous_inner_derived_class->test_int << std::endl;
        std::cout << "Inner Derived Class test_int = " << inner_class_ptr_to_inner_derived_class->test_int << std::endl;
    }
};

方案2:动态分配内存(需管理内存)

如果需要按需创建实例,可使用new在堆上分配对象,此时对象生命周期由程序员控制,需注意添加析构函数释放内存避免泄漏:

class Base {
public:
    class Inner {
    public:
        int test_int = 1;
    };

    Inner* inner_class_ptr_to_anonymous_inner_derived_class;
    Inner* inner_class_ptr_to_inner_derived_class;
};

class Derived : public Base {
public:
    class Inner_Derived : public Base::Inner {};
    class : public Base::Inner {}anonymous_inner_derived;
    Derived()
    {
        inner_class_ptr_to_inner_derived_class = new Inner_Derived(); // 堆上分配
        inner_class_ptr_to_anonymous_inner_derived_class = &anonymous_inner_derived;
    }
    // 析构函数释放堆内存
    ~Derived() {
        delete inner_class_ptr_to_inner_derived_class;
    }
};

class Derived_GrandChild : public Derived {
public:
    Derived_GrandChild() {  
        std::cout << "Anonymous Inner Derived Class test_int = " << inner_class_ptr_to_anonymous_inner_derived_class->test_int << std::endl;
        std::cout << "Inner Derived Class test_int = " << inner_class_ptr_to_inner_derived_class->test_int << std::endl;
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:01:29