【问题标题】:How to create objects in a function outside of main?如何在 main 之外的函数中创建对象?
【发布时间】:2013-06-24 01:37:30
【问题描述】:

一切运行良好,但我的问题是我的主要功能太长了。有没有办法在主功能之外创建战斗场景?我已经尝试过了,但是如果我将战斗场景——让我们说“Battle()”——放在头文件或其他东西中,那么我的对象会产生错误。有什么方法可以使我在 main 函数之外的 main 中声明的对象。也许使用指针或其他东西?

 int main()
    {
        Hero Me(100,20,30,40);//Created using overloaded constructor
        Monster m(100,16,18,20);//creates a monster object and uses overloaded constructor to initialize

    cout << "\nAttacking!\n";

//I want this part to be in a function called Battle() outside of main
    while ((Me.getHp() > 0) && (m.getHp() > 0))//Generates error if object not declared in main
    {   
        cout << "\nYour hp is: " << Me.getHp() << endl;
        cout << "The enemy's hp is: "<< m.getHp() << endl;
        cout << "\nThe monster has attacked you!\n";
        cout << "You received " << m.getAttack() << " damage;" << endl;
        Me.damageTaken(m.getAttack());//Me.setHp(Me.getHp() - m.getAttack());//Me.setHp(m.getStrength());
        if(Me.getHp() > 0)//Check if still alive
        {
            cout << "\nYour hp is now: " << Me.getHp() << endl;
            //cout << "Enemy hp is: "<< m.getHp() << endl;
            cout << "\nNow you attacked!\nYou have dealt "<< Me.getAttack() << " Damage" << endl;
            m.damageTaken(Me.getAttack());//m.setHp(m.getHp() - Me.getAttack());//m.setHp(Me.getAttack());

            if(m.getHp() > 0)//Check if still alive
            {
                cout << "Enemy hp is now: " << m.getHp() << endl;
                cout << "\nAttacking again!\n";
            }
        }

    } 
        if ((Me.getHp() > 0) && (m.getHp() <= 0))
                cout <<"\nCongratulations! You killed the enemy!" << endl;

        else if ((Me.getHp() <= 0) && (m.getHp() > 0))
                cout << "You have died!" << endl;




    cin.sync();
    cin.get();
    return 0;
}

如果代码如下:

//Hero.h
class Hero:
    public Character
{
public:
    Hero();
    Hero(int, int, int, int);
    ~Hero();

};

//Hero.cpp
Hero::Hero(int newHp, int newLevel, int newAttack, int newDef)
    : Character(newHp, newLevel, newAttack, newDef)
{
    cout << "Hero created using Overloaded function!\n";
    hp = newHp;
    cout << "Hp is: "<< hp << endl;
    level = newLevel;
    cout << "level is: " << level << endl;
    attack = newAttack;
    cout << "Attack is: " << attack << endl;
    defense = newDef;
    cout << "Defense is: " << defense << endl;
    // logging goes here
    // note that you don't need HeroLevel etc. at all any more, just use level
}

Hero::~Hero()
{
    cout << "Hero destroyed!\n";
}


//Monster.h
class Monster:
    public Character //Hero
{
public:
    Monster();
    Monster(int, int, int, int); //explicit
        //:Character(){};
    //Monster(int);
    ~Monster();
};

//Monster.cpp
Monster::Monster(int newHp, int newLevel, int newAttack, int newDef)
    //: hp(newHp), level(newLevel), attack(newAttack), defense(newDef)//initialize list
{
    cout << "Monster created using Overloaded function!\n";
    hp = newHp;
    cout << "Hp is: "<< hp << endl;
    level = newLevel;
    cout << "level is: " << level << endl;
    attack = newAttack;
    cout << "Attack is: " << attack << endl;
    defense = newDef;
    cout << "Defense is: " << defense << endl;
}

Monster::~Monster()
{
    cout << "\nMonster Destroyed";
}

//Character.h
class Character
{

protected://not private, so derived class can use it
    int level;
    int hp;
    int attack;
    int defense;
    Character(); // zero everything by default
    Character(int); // randomly generate everything
    Character(int, int, int, int); // populate explicitly
    ~Character();
public:
    int getAttack() const { return attack; }
    int getDefense() const { return defense; }
    int getHp() const { return hp; }
    int getlevel() const { return level; }

    void setAttack(int);
    void setDefense(int);
    void setStrength(int);
    void setHp(int);
    void setlevel(int);
    void damageTaken(int);

//Character.cpp
Character::Character() : level(0), hp(0), attack(0), defense(0) {}

Character::Character(int hit, int lvl, int att, int def)
 : level(lvl), hp(hit), attack(att), defense(def){}


Character::~Character()
{
    cout << "Character has been destroyed!\n";
}

【问题讨论】:

  • 是的,你当然可以做你想做的事。如果您向我们展示您的尝试,它将有所帮助。改正错误的地方可能比为你写整件事更容易。
  • 我尝试了许多不同的方法,但代码太多了。我试图将主要对象之前的对象作为全局对象,我尝试将它们放在不同的文件中并将原型放在标题中,我什至尝试将它们设为静态。没有任何效果!
  • 我很确定这可以简化为一个更小的代码示例。
  • 欢迎来到 Stack Overflow。你的问题有点不清楚。最好将失败的尝试连同遇到的错误一起显示出来。为什么不直接从 Character 中创建一个成员函数“Battle(Character&对手)”并在那里实现战斗代码。您可以将其归结为 while (!isOver()) { doCombatFrame(opponent); }; cout &lt;&lt; "Winner is: " &lt;&lt; (opponent.isDead()) ? "me" : "the enemy" &lt;&lt; endl; 之类的内容,并在另一个新成员 doCombatFrame() 中实现循环部分。

标签: c++ class function oop object


【解决方案1】:

你可以通过三种方式做到这一点:

  1. 返回副本。这可能是首选方式,对于简单对象来说也是最简单的方式。

    此类函数的示例:

    Hero create_hero()
    {
        Hero hero{...};
    
        // Other stuff
    
        return hero;
    }
    
  2. 返回引用。这里最大的警告是您不能返回对局部变量的引用,您必须返回对存储在其他地方(例如向量中)的数据的引用。

  3. 返回指针。这与数字 2 有相同的警告,返回一个指向局部变量的指针,例如return &amp;some_local_var; 是个坏主意。

    此类函数的示例:

    std::unique_ptr<Hero> create_hero()
    {
        auto hero = std::unique_ptr<Hero>(new Hero{...});
    
        // other stuff
    
        // remember that `hero` is a pointer, so the `->` operator has to be used
        // when dereferencing the variable
        // e.g. `hero->some_function()`
    
        return hero;
    }
    

对于第 1 点,如果您有任何类型的复杂对象,您应该了解the rule of three

对于第 3 点,我建议使用智能指针,例如 std::unique_ptrstd::shared_ptr,如我的示例所示。

【讨论】:

  • 指针还没学过,不过这个很清楚!非常感谢!顺便问一下,你有什么推荐的书籍或网站可以让我学习指针和参考吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
相关资源
最近更新 更多