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

C++继承场景下子类对象成员变量全为0/False问题排查

问题分析与修复方案

你的问题核心有两个:

  • Weapon类的成员变量都是private权限,子类WeaponShortBow根本无法访问这些成员,就算子类构造函数接收了参数,也没法赋值给父类的成员
  • WeaponShortBow的构造函数只是接收了参数,但完全没做任何赋值操作;同时父类Weapon的默认构造函数也没有初始化成员,所以这些变量都会被C++设置为默认零值(int为0,bool为false,指针为nullptr)

步骤1:给Weapon类添加带参数的构造函数

把Weapon的无参构造函数替换成带参数的版本,用初始化列表初始化所有成员,这样子类可以通过调用父类构造函数来完成成员初始化。

修改后的Weapon.h

#ifndef DNDTESTY_WEAPON_H
#define DNDTESTY_WEAPON_H
#include "Effects/Effect.h"

class Weapon {
public:
    // 带参数的构造函数,设置默认值替代原无参构造
    Weapon(int Amunition = 0,
           int Range = 0,
           int TypeOfDice = 0,
           int NumberOfDice = 0,
           int HitModiff = 0,
           bool IsFniesse = false,
           bool IsTwoHanded = false,
           bool IsMagical = false,
           bool IsLight = false,
           char Category = '\0',
           Effect* effect = nullptr);

    void removeAmmo();

    int getRange() const;

    // 修复原and_so_on函数的错误逻辑,示例返回HitModiff
    int getHitModiff() const;

private:
    int Amunition;
    int Range;
    int TypeOfDice;
    int NumberOfDice;
    int HitModiff;
    bool IsFniesse;
    bool IsTwoHanded;
    bool IsMagical;
    bool IsLight;
    char Category;
    Effect *effect;
};
#endif

修改后的Weapon.cpp

#include "Weapon.h"

// 用初始化列表初始化所有父类成员
Weapon::Weapon(int Amunition,
               int Range,
               int TypeOfDice,
               int NumberOfDice,
               int HitModiff,
               bool IsFniesse,
               bool IsTwoHanded,
               bool IsMagical,
               bool IsLight,
               char Category,
               Effect* effect)
    : Amunition(Amunition),
      Range(Range),
      TypeOfDice(TypeOfDice),
      NumberOfDice(NumberOfDice),
      HitModiff(HitModiff),
      IsFniesse(IsFniesse),
      IsTwoHanded(IsTwoHanded),
      IsMagical(IsMagical),
      IsLight(IsLight),
      Category(Category),
      effect(effect)
{}

void Weapon::removeAmmo() {
    this->Amunition -= 1;
}

int Weapon::getRange() const {
    return Range;
}

int Weapon::getHitModiff() const {
    return HitModiff;
}

步骤2:修改WeaponShortBow的构造函数,调用父类构造

子类构造函数需要通过初始化列表调用父类的带参构造函数,把接收的参数传递进去,完成成员初始化。

修改后的WeaponShortBow.cpp

#include "WeaponShortBow.h"
#include "Effects/NoEffect.h"

// 通过初始化列表调用父类Weapon的构造函数,传递参数
WeaponShortBow::WeaponShortBow(
        int Amunition,
        int Range,
        int TypeOfDice,
        int NumberOfDice,
        int HitModiff,
        bool IsFniesse,
        bool IsTwoHanded,
        bool IsMagical,
        bool IsLight,
        char Category)
    : Weapon(Amunition, Range, TypeOfDice, NumberOfDice, HitModiff, IsFniesse, IsTwoHanded, IsMagical, IsLight, Category)
{}

Effect* WeaponShortBow::ApplyShortBowEffect(){
    Effect* tmp = new NoEffect;
    return tmp;
}

步骤3:修复其他语法错误

  • Actor.cpp中的some other functions()语法错误,函数名不能包含空格,改为void Actor::someOtherFunctions() {}
  • 确保Weapon.h末尾添加了#endif(原代码中遗漏)

修改完成后,当你在Actor构造函数中创建new WeaponShortBow时,会自动使用子类的默认参数,传递给父类构造函数完成成员初始化,就不会再出现所有变量为0或false的情况了。

内容的提问来源于stack exchange,提问作者Szymon Nowaczyk - Słomian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:45:06