2015-12-21 63 views
0

我製作了一個小店主計劃,允許玩家從店主手中購買物品並將物品存儲在玩家庫存中。我第一次使用面向對象技術,並遇到了一個我無法解決的問題。第一次創建了一個跨越幾個類的程序,但我遇到了函數調用的問題。

我遇到的問題是'ShopKeeper.cpp','PurchaseItem'這些物品沒有添加到玩家庫存中。我正在做的函數調用有問題。但是如果我在main中調用'Player.AddItem()',它可以正常工作。從我的理解,我組織我的代碼的方式是正確的?我覺得這是最可讀的 - 對我來說至少 - 儘管可以自由地說不。

這是我到目前爲止的代碼。很抱歉,代碼很長,我不確定是否有限制,您可以粘貼到這裏,但我認爲最好展示一下。

非常感謝你提前。

// Shop.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include "Player.h" 
#include "ShopKeeper.h" 

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <string> 

int main() 
{ 
    Player player; //The player 
    ShopKeeper shopKeeper; //The shop keeper 

    int responce; //Menu navigation 
    std::cout << "Greetings " << player.GetName() << ". Feel free to browse my wares." << "\n"; 
    std::cout << "1: Purchase Items. 2: Sell Items. 3: List Your Items. 4: Show Gold. 5: Exit" << "\n"; 

    do 
    { 
     std::cin >> responce; 

     switch (responce) 
     { 
     case 1: 
      shopKeeper.PurchaseItem(); 
      break; 

     case 2: 
      shopKeeper.SellItem(); 
      break; 

     case 3: 
      player.ListInventory(); 
      break; 

     case 4: 
      std::cout << "You have " << player.GetGold() << " gold coins." << "\n"; 
      break; 

     case 5: 
      std::cout << "Thank you for shopping." << "\n"; 
      break; 

     default: 
      std::cout << "Please enter valid data." << "\n"; 
      std::cout << "1: Purchase Items. 2: Sell Items. 3: List Your Items. 4: Show Gold. 5: Exit" << "\n"; 
     } 
    } while (responce != 5); 

    /* 
    //This works 
    player.AddItem("Mace", 30); 
    player.ListInventory(); 
    std::cout << player.GetGold(); 
    */ 

    //Keep window open 
    std::string barn; 
    std::cin >> barn; 

    return 0; 
} 

ShopKeeper.h

#pragma once 
#include <string> 

class ShopKeeper 
{ 
private: 



public: 
    void PurchaseItem(); //Shop keeper has player buy items from them 
    void SellItem(); //Shop keeper sells item to player 

    ShopKeeper(); 
    ~ShopKeeper(); 

}; 

ShopKeeper.cpp

#include "stdafx.h" 
#include "ShopKeeper.h" 
#include "Player.h" 

#include <iostream> 

//Player purchases item from shop keeper 
void ShopKeeper::PurchaseItem() 
{ 
    Player player; 

    int responce = 0; //Menu navigation 
    std::cout << "1: Mace - 30 gold. 2: Bow - 50 gold. 3: Boots - 10 gold. 4: Bearskin - 75 gold. 5: Helmet - 25 gold." << "\n"; 

    do 
    { 
     std::cin >> responce; 

     switch (responce) 
     { 
     case 1: 
      player.AddItem("Mace", 30); 
      break; 

     case 2: 
      player.AddItem("Bow", 50); 
      break; 

     case 3: 
      player.AddItem("Boots", 10); 
      break; 

     case 4: 
      player.AddItem("Bearskin", 75); 
      break; 

     case 5: 
      player.AddItem("Helmet", 25); 
      break; 

     default: 
      std::cout << "Please enter valid data." << "\n"; 
      std::cout << "1: Mace - 30 gold. 2: Bow - 50 gold. 3: Boots - 10 gold. 4: Bearskin - 75 gold. 5: Helmet - 25 gold." << "\n"; 
     } 
    } while (responce > 5 || responce < 1); 

} 

//Shop keeper sells item to player 
void ShopKeeper::SellItem() 
{ 
    Player player; 
    int responce = 0; 
    player.ListInventory(); 

    switch (responce) 
    { 
    case 1: 
     player.SellItem(0, 20); 
     break; 

    case 2: 
     player.SellItem(1, 20); 
     break; 

    case 3: 
     player.SellItem(2, 20); 
     break; 

    case 4: 
     player.SellItem(3, 20); 
     break; 

    case 5: 
     player.SellItem(4, 20); 
     break; 

    default: 
     std::cout << "Please enter valid data." << "\n"; 
     player.ListInventory(); 
    } 
} 

ShopKeeper::ShopKeeper() 
{ 
} 


ShopKeeper::~ShopKeeper() 
{ 
} 

Player.h

#pragma once 

#include <vector> 

class Player 
{ 
private: 
    const int maxNumbItems = 5; //Maximum number of items that inventory can store 

    int goldCoins = 150, //Amount of gold coins the player has 
     numbOfItems = 0; //Number of con-current items player holds 
    std::vector<std::string> inventory; //Players inventory 
    std::string name = "Gorrex"; //Players name 

public: 
    std::string GetName(); //Get the players name 
    std::string AddItem(std::string item, int itemPrice); // Add item to players inventory 
    void Player::SellItem(int itemNum, int itemPrice); //Sell item 
    bool IsInventoryFull(); //Check to see if players inventory is full 
    int InventoryCapacity(); //Get capacity of inventory 
    int GetGold(); //Get players gold 
    void ListInventory(); 


    Player(); 
    ~Player(); 
}; 

Player.cpp

#include "stdafx.h" 
#include "Player.h" 

#include <iostream> 
#include <ostream> 
#include <string> 

//Get the players name 
std::string Player::GetName() 
{ 
    return name; 
} 

//Add item to players inventory 
std::string Player::AddItem(std::string item, int itemPrice) 
{ 
    //Is players inventory not full? 
    if (IsInventoryFull()) 
    { 
     std::cout << "Inventory is full."; 
    } 

    else 
    { 
     //Can player afford item? 
     if (goldCoins >= itemPrice) 
     { 
      goldCoins -= itemPrice; 
      numbOfItems++; 
      std::cout << "You have purchased " << item << "." << "\n"; 
      inventory.push_back(item); //Add item to inventory 
      return item; 
     } 

     //If player cant afford item 
     else 
     { 
      std::cout << "You cannot afford this item." << "\n"; 
     } 
    } 
} 

void Player::SellItem(int itemNum, int itemPrice) 
{ 
    char responce; 
    std::cout << "Are you sure you want to sell: " << inventory[itemNum] << "? 'y' - Yes. 'n' - No." << "\n"; 
    std::cin >> responce; 

    switch (responce) 
    { 
    case 'y': 
     numbOfItems++; 
     goldCoins += itemPrice; 
     inventory.erase(inventory.begin() + itemNum); 
     break; 

    case 'n': 
     std::cout << "That is ok." << "\n"; 
     break; 

    default: 
     std::cout << "Please enter correct data." << "\n"; 
    } 
} 




//Check to see if players inventory is full 
bool Player::IsInventoryFull() 
{ 
    //If players inventory isnt full 
    if (numbOfItems < maxNumbItems) 
    { 
     return false; 
    } 

    //If players inventory is full 
    else 
    { 
     return true; 
    } 
} 

//Return size of players inventory 
int Player::InventoryCapacity() 
{ 
    return inventory.size(); 
} 

//Get the players gold 
int Player::GetGold() 
{ 
    return goldCoins; 
} 

//List the players inventory 
void Player::ListInventory() 
{ 
    int itemNumb = 0; //item number in menu 

    for (int i = 0; i < inventory.size(); i++) 
    { 
     itemNumb++; 
     std::cout << itemNumb << ": " << inventory[i] << "\n"; 
    } 

    /* //If inventory is empty 
    if (inventory.empty()) 
    { 
     std::cout << "inventory is empty" << "\n"; 
    }*/ 

} 

Player::Player() 
{ 
} 


Player::~Player() 
{ 
} 

回答

3

在店主您聲明的Player本地實例,該函數調用後會消失:

void ShopKeeper::PurchaseItem() 
{ 
    Player player; 

製作PurchaseItem接受Player& player而不是聲明本地Player

SellItem也是如此。您需要指定要出售給誰。

然後在你main你可以這樣說:

switch (responce) 
{ 
case 1: 
    shopKeeper.PurchaseItem(player); 
    break; 

case 2: 
    shopKeeper.SellItem(player); 
//... 
+0

非常感謝你解決了我的問題。你知道我可以對我的代碼進行其他改進嗎? –

+0

@RyanSwann:那麼你可能想讓'Inventory'成爲自己的類。然後玩家將擁有一個它的實例。這使您可以製作有庫存的店主(最終從同一基地繼承播放器和店主)。一個店主的定價項目將成爲經濟體系的一部分,但現在你可以對項目價值進行硬編碼。作爲該項目的一個領域。含義'Item'將成爲它自己的類,帶有一個名稱和一個值。 – AndyG

2

PlayerShopKeeper是本地的ShopKeeper和無關Playermain

您必須通過PlayerShopKeeper方法。 您有幾種選擇:通過它的ShopKeeper 構造函數或引用傳遞給方法:

更換

void ShopKeeper::PurchaseItem() 
{ 
    Player player; 
    // ... 

通過

void ShopKeeper::PurchaseItem(Player& player) 
{ 
    // ... 

,並調用它

shopKeeper.PurchaseItem(player); 
+0

非常感謝你解決了我的問題。你知道我可以對我的代碼進行其他改進嗎? –

+0

作爲本地改進:添加缺少的'const',刪除不需要的代碼作爲空的構造函數/析構函數。 – Jarod42

+0

由於結構改進:我會將一些邏輯從'Player'移動到'ShopKeeper','Inventory' /'Item'類是有意義的(並且會簡化類Player)。一個類處理問題系統避免那些'switch case'應該也不錯。 – Jarod42

相關問題