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

手动调用析构函数导致C++ Creature对象重复销毁问题求助

问题分析与解决方案

问题根源

你手动调用c.~Creature()销毁栈对象的操作是错误的:

  • 栈上的变量c1会在main函数结束时由编译器自动触发析构函数,这就导致同一对象被析构两次。
  • 第一次手动析构后,对象内存已被标记为无效,第二次自动析构时访问name会出现空值,所以输出 is destroyed.。
  • C++中栈对象的生命周期由编译器管理,手动调用析构函数属于未定义行为,绝对不能这么做。

另外你写的检查条件还有错误:原代码里判断strength >100不符合题目要求(题目要求strength范围是0-50),且getPV() ==0 || getPV() <=0是重复判断,正确的边界应该是hp <0 || hp>100、strength <0 || strength>50。


可行解决方案

方案1:使用动态分配对象(推荐)

将对象改为堆上分配,不符合条件时用delete手动销毁,避免栈对象的自动析构冲突:

void checkCreature(Creature* c) {
    // 修正边界判断逻辑
    if (c->getPV() < 0 || c->getPV() > 100 || c->getStrength() < 0 || c->getStrength() > 50) {
        delete c;
        c = nullptr; // 置空指针,避免野指针问题
    }
}

int main() {
    Creature* c1 = new Creature();
    c1->fillCreature();
    c1->creatureShowInfo();
    checkCreature(c1);
    
    // 检查指针有效性,避免重复delete
    if (c1 != nullptr) {
        delete c1;
    }
    return 0;
}

方案2:用工厂函数创建有效对象

给Creature类添加静态工厂函数,只有属性符合要求时才返回有效对象,否则返回空:

#include <optional>
#include <string>
#include <iostream>

class Creature {
private:
    std::string name;
    int pv;
    int strength;
    // 私有构造函数,强制通过工厂创建对象
    Creature(const std::string& n, int h, int s) : name(n), pv(h), strength(s) {}

public:
    // 工厂函数:检查属性合法性,返回可选对象
    static std::optional<Creature> create(const std::string& name, int hp, int strength) {
        if (hp >= 0 && hp <= 100 && strength >= 0 && strength <= 50) {
            return Creature(name, hp, strength);
        }
        return std::nullopt;
    }

    void creatureShowInfo() {
        std::cout << "Name : " << name << "\nHP : " << pv << "\nStrength : " << strength << std::endl;
    }

    ~Creature() {
        std::cout << name << " is destroyed." << std::endl;
    }
};

int main() {
    std::string name;
    int hp, strength;
    // 模拟输入逻辑
    std::cout << "Creature's name :";
    std::cin >> name;
    std::cout << "Creature's health (between 0 and 100) :";
    std::cin >> hp;
    std::cout << "Creature's strength (between 0 and 50) :";
    std::cin >> strength;

    auto creatureOpt = Creature::create(name, hp, strength);
    if (creatureOpt) {
        creatureOpt->creatureShowInfo();
    } else {
        std::cout << "Strength value incorrect." << std::endl;
    }
    return 0;
}

方案3:标记对象为无效状态

如果必须使用栈对象,可以给类添加isValid标记,析构函数只在对象有效时输出信息:

class Creature {
private:
    std::string name;
    int pv;
    int strength;
    bool isValid = true; // 标记对象是否有效

public:
    // 成员函数实现...
    void invalidate() {
        isValid = false;
        // 可在此清理资源,但不要调用析构
    }

    int getPV() const { return pv; }
    int getStrength() const { return strength; }
    void fillCreature() { /* 原输入逻辑 */ }
    void creatureShowInfo() { /* 原输出逻辑 */ }

    ~Creature() {
        if (isValid) {
            std::cout << name << " is destroyed." << std::endl;
        }
    }

    friend void checkCreature(Creature& c);
};

void checkCreature(Creature& c) {
    if (c.getPV() < 0 || c.getPV() > 100 || c.getStrength() < 0 || c.getStrength() > 50) {
        c.invalidate();
    }
}

int main() {
    Creature c1;
    c1.fillCreature();
    c1.creatureShowInfo();
    checkCreature(c1);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:45:21