首页 > 解决方案 > 从指向其成员类的指针打印字符串

问题描述

所以我试图打印一个字符串,但没有输出。然而,类中的其他值打印得很好。

在 main 中,我有一个 for 循环,用于打印 Skill 类的值。在技​​能中,我有一个指向能力类的指针。

class Skill {
private:
    Ability* ability;
public:
    Ability* GetAbility() {
        return ability;
    };
}

它在构造函数中被赋值,如下所示:

Skill::Skill(Ability* ability){
    this->ability = ability;
 }

能力类只包含一个名称和一个分数。

class Ability {
private:
    string name;
    float score;
    public:
    Ability(string name, float score) {
        this->name = name;
        this->score = score;
    };
    string Name() { return name; }
    float GetScore() { return score; }
};

现在主要是我创建一些技能并为其分配能力。作为一个容器类,它初始化向量中的一些能力,我可以根据它的名称获得一个能力。

Skill s* = new Skill[2]
s[0] = Skill(&as.GetAbility("Strength"));
s[1] = Skill(&as.GetAbility("Charisma"));

然后我们打印

cout << s[i].GetAbility()->Name() << " " << s[i].GetAbility()->GetScore();

然而,我得到的唯一输出是分数。没有名字,我无法弄清楚。我已经尝试了一些东西,但仍然注意到打印。我确定我错过了一些简单的东西,这会让我大吃一惊,但在我的辩护中,我已经有 10 多年没有编写 C++ 了。提前致谢。

编辑: as.GetAbility 看起来像这样:

Ability AbilityScores::GetAbility(string abilityName) {
    for (int i = 0; i < abilityScores.size(); i++) {
        if (abilityScores[i].Name() == abilityName) {
            return abilityScores[i];
        }
    }
    return Ability();
}

abilityScores 是一个向量

标签: c++string

解决方案


您的AbilityScores::GetAbility()方法按 valueAbility返回一个对象,这意味着它返回source的副本,因此您的对象最终将持有指向在构造函数退出后立即被销毁的临时对象的悬空指针。所以你的代码有未定义的行为AbilitySkillAbilitySkill

AbilityScores::GetAbility()需要通过引用返回Ability对象:

Ability& AbilityScores::GetAbility(string abilityName) {
    for (int i = 0; i < abilityScores.size(); i++) {
        if (abilityScores[i].Name() == abilityName) {
            return abilityScores[i];
        }
    }
    throw ...; // there is nothing to return!
}

...

Skill s* = new Skill[2];
s[0] = Skill(&as.GetAbility("Strength"));
s[1] = Skill(&as.GetAbility("Charisma"));

...

如果您想在未找到Ability时返回默认值,请考虑使用而不是:abilityNamestd::mapstd::vector

private:
    std::map<std::string, Ability> abilityScores;

AbilityScores::AbilityScores() {
    abilityScores["Strength"] = Ability("Strength", ...);
    abilityScores["Charisma"] = Ability("Charisma", ...);
    ...
}

Ability& AbilityScores::GetAbility(string abilityName) {
    // if you don't mind Name() returning "" for unknown abilities...
    return abilityScores[abilityName];

    // otherwise...
    auto iter = abilityScores.find(abilityName);
    if (iter == abilityScores.end()) {
        iter = abilityScores.emplace(abilityName, 0.0f).first;
    }
    return iter->second;
}

...

Skill s* = new Skill[2];
s[0] = Skill(&as.GetAbility("Strength"));
s[1] = Skill(&as.GetAbility("Charisma"));

...

否则,改为通过指针Ability返回对象:

Ability* AbilityScores::GetAbility(string abilityName) {
    for (int i = 0; i < abilityScores.size(); i++) {
        if (abilityScores[i].Name() == abilityName) {
            return &abilityScores[i];
        }
    }

    return nullptr;
    // or:
    abilityScores.emplace_back(abilityName, 0.0f);
    return &(abilityScores.back());
}

...

Skill s* = new Skill[2];
s[0] = Skill(as.GetAbility("Strength"));
s[1] = Skill(as.GetAbility("Charisma"));

...

推荐阅读