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

C++类对象无法存储整数并跨函数正确输出问题求助

问题分析与解决

核心问题

你遇到的是局部对象作用域与生命周期问题:

  • lich_swamp()中创建的Inv inv是该函数的局部对象,它的coins值仅属于这个对象;
  • menu()里重新创建了一个全新的Inv inv局部对象,这个对象的coins是类默认初始化的0,和之前lich_swamp()里的对象无任何关联,所以显示0是正常的(异常长负数可能是未正确初始化的情况,但你的类已默认给coins赋值0,所以大概率显示0)。

解决方法

下面给出几种适合新手的实现方案,按推荐程度排序:


方案1:传递对象引用(推荐,符合面向对象设计)

让menu()函数接收Inv对象的引用,这样它操作的是外部传入的真实背包对象,而非新建的空对象。

  1. 修改menu()函数定义:
// 参数为Inv&,表示引用传递
void menu(Inv& inv)
{
    std::cout << "0:{return to game}\n";
    std::cout << "1:{view inventory}\n";
    std::cout << "2:{view achievements}\n";
    std::cout << "3:{player info}\n";
    int menu_choice;

    std::cin >> menu_choice;

    switch (menu_choice)
    {
    case 0:
        system("CLS");
        break;
    case 1:
        system("CLS");
        inv.print_inv();
        return;
    case 2:
        system("CLS");
        //num_twopr(ach);
        return;
    case 3:
        system("CLS");
        plyr_print();
        return;
    }
}
  1. 修改Inv::print_inv()中调用menu()的代码,传递当前对象的引用:
void Inv::print_inv()
{
    int inv_choice;
    std::cout << "x" << coins << " Coin(s) in your inventory.";
    std::cout << "\n0: [RETURN TO MENU]\n";
    std::cin >> inv_choice;
    switch (inv_choice)
    {
    case 0:
        system("CLS");
        menu(*this); // *this代表当前Inv对象本身,传递引用给menu
        break;
    }
}
  1. 在lich_swamp()中调用menu()时,传入当前的inv对象:
void lich_swamp()
{
    Inv inv;
    do
    {
        std::cout << "---Irrelevant---";
        std::cout << "[Insert Number]\n";
        inv.c_add();
        
        if (inv.coins <= 4)
        {
            system("CLS");
            inv.c_print();
            // 这里添加调用menu的逻辑,比如玩家选择返回菜单时
            menu(inv);
            break;
        }
        else if (inv.coins > 4)
        {
            system("CLS");
            std::cout << "---Irrelevant---";
            dth_e1();
            console_death();
            return;
        }
    } while (inv.coins < 1);
}

方案2:使用全局对象(新手易上手,但不推荐大型项目)

把Inv对象定义在所有函数外部,变成全局变量,这样所有函数都能访问同一个对象:

// 在main.cpp最顶部、所有函数之前定义
Inv player_inv;

void lich_swamp()
{
    do
    {
        std::cout << "---Irrelevant---";
        std::cout << "[Insert Number]\n";
        player_inv.c_add(); // 使用全局对象
        
        if (player_inv.coins <= 4)
        {
            system("CLS");
            player_inv.c_print();
            break;
        }
        else if (player_inv.coins > 4)
        {
            system("CLS");
            std::cout << "---Irrelevant---";
            dth_e1();
            console_death();
            return;
        }
    } while (player_inv.coins < 1);
}

void menu()
{
    std::cout << "0:{return to game}\n";
    std::cout << "1:{view inventory}\n";
    std::cout << "2:{view achievements}\n";
    std::cout << "3:{player info}\n";
    int menu_choice;

    std::cin >> menu_choice;

    switch (menu_choice)
    {
    case 0:
        system("CLS");
        break;
    case 1:
        system("CLS");
        player_inv.print_inv(); // 使用全局对象
        return;
    case 2:
        system("CLS");
        //num_twopr(ach);
        return;
    case 3:
        system("CLS");
        plyr_print();
        return;
    }
}

方案3:单例模式(适合全局唯一的背包)

如果游戏中玩家只有一个背包,可以把Inv设计成单例类,确保整个程序只有一个实例:

// 修改Inv类的头文件
#ifndef INV_UTILS
#define INV_UTILS
#include "C:/Otherincludedfile.h"
#include <iostream>

class Inv
{
private:
    int longsword = 0;
    int coins = 0;
    // 私有构造函数,禁止外部创建对象
    Inv() {}
public:
    // 获取唯一实例的静态方法
    static Inv& getInstance() {
        static Inv instance;
        return instance;
    }
    // 禁止拷贝和赋值
    Inv(const Inv&) = delete;
    void operator=(const Inv&) = delete;

    void c_add();
    void c_print();
    void print_inv();
    // 提供访问coins的方法(封装成员变量,符合面向对象规范)
    int getCoins() const { return coins; }
    void setCoins(int val) { coins = val; }
};

#endif

// 修改c_add函数
void Inv::c_add()
{
    std::cin >> coins;
}

// 使用时,所有地方都通过Inv::getInstance()获取同一个对象
void lich_swamp()
{
    Inv& inv = Inv::getInstance();
    do
    {
        std::cout << "---Irrelevant---";
        std::cout << "[Insert Number]\n";
        inv.c_add();
        
        if (inv.getCoins() <= 4)
        {
            system("CLS");
            inv.c_print();
            break;
        }
        else if (inv.getCoins() > 4)
        {
            system("CLS");
            std::cout << "---Irrelevant---";
            dth_e1();
            console_death();
            return;
        }
    } while (inv.getCoins() < 1);
}

void menu()
{
    std::cout << "0:{return to game}\n";
    std::cout << "1:{view inventory}\n";
    std::cout << "2:{view achievements}\n";
    std::cout << "3:{player info}\n";
    int menu_choice;
    Inv& inv = Inv::getInstance();

    std::cin >> menu_choice;

    switch (menu_choice)
    {
    case 0:
        system("CLS");
        break;
    case 1:
        system("CLS");
        inv.print_inv();
        return;
    case 2:
        system("CLS");
        //num_twopr(ach);
        return;
    case 3:
        system("CLS");
        plyr_print();
        return;
    }
}

关键知识点补充

  • 局部对象:在函数内部定义的对象,生命周期从定义处开始,到函数结束时销毁,每个函数的局部对象都是独立的。
  • 引用传递:函数参数用Type&时,传递的是对象本身的引用,操作的是原对象而非副本。
  • 封装:方案3把coins设为私有,通过get/set方法访问,是面向对象的良好实践,避免直接修改成员变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:37:07