7
\$\begingroup\$

I would appreciate any constructive feedback on my game, I intend to add simple 2d graphics at some point but want to make the "skeleton' of the game first using just text.

One question I had is a suggestion to better implement the fight sequence that is currently under Mob.h under the functions attackoutcome and defendoutcome. I feel like it should be somewhere else and adding into main doesn't seem right to me, but I also don't feel like it constitutes creating a new class.

Main.cpp

// Textadventure.cpp : Defines the entry point for the console application.
//
//to-do: 2. create mobs and items/3. create story and choices system/1. C. Improve combat(loot system and stats should play a role defense??),B. MOSTLY DONE -> mobs(need stats and inv defense??), and A. character (decide how stats effect things&balancing defense??) by integrating stats system into everything D. after integrating make touches to balance xxx ____FUTURE____create small test story/ continue adding features and full game
//ALSO ADD CLEAR SCREEN ABILITY AND INTEGRATE IT! IDEA-armor covers body parts and depending on type of attack certain chance to hit a body part, damage depends on type of armor and weapon - chance to cripple/disarm/ internal bleeding/ etc...
// MOB - needs work CHAR- needs work BACK - finished ITEM - done
#include "stdafx.h"
#include <string>
#include <iostream>
#include "Character.h"
#include "Llist.h"
#include "Item.h"
#include "Mob.h"
#include <cstdlib>

using namespace std;

void generateList(Llist& tempList);
Character attackScene(Character main, Mob Goblin);


int main()
{
    int a;
    Character main; 
    string name;
    int stats[8];
    int * statPtr = stats;
    cout << "Enter Name:";
    cin >> name;
    for (int i = 0; i < 7; i++) {
        stats[i]=5;
    }
    main.characterCreation(statPtr, name);
    cout << main.getName()<<endl<<"HP:"<<main.getHp()<<endl<<"att"<<main.getAttack()<<endl;
    cin >> a;
    Llist itemList;
    generateList(itemList);
    main.addInv(itemList.find(1001));
    main.addInv(itemList.find(1000));
    main.addInv(itemList.find(2001));
    main.addInv(itemList.find(2000));
    main.showInv();
    Mob Goblin(statPtr, "Goblin");
    Goblin.addInv(itemList.find(1001));
    Goblin.addInv(itemList.find(1000));
    Goblin.addInv(itemList.find(2001));
    Goblin.addInv(itemList.find(2000));
    cin >> a;
    main = attackScene(main,Goblin);
    cout << main.getHp();
    cin >> a;


}

void generateList(Llist & itemList) { //as each item is created it is stored in a Llist, each node of the Llist holds an item and is represented and found by that items ID#
    //to add an item first create the item and its values (ID, weight, attack bonus, price, name) then, insert each item into list (ID, item)
    //to access an item after it is placed into a list use find function .find(id #)
    Item a(1000,15,10,50,"Iron Sword");
    Item b(1001,10,5,20,"Wooden Club");
    Item c(2000, 30, 20, 250, "Iron armor");
    Item d(2001, 5, 5, 50, "Leather armor");
    itemList.insert(1000,a); //1000 is the ID number and is stored as the value of the node, the item "a" is stored in that node also.
    itemList.insert(1001,b);
    itemList.insert(2000, c);
    itemList.insert(2001, d);
    return;
}

Character attackScene(Character main, Mob Goblin) 
{
    cout << main.getName() << endl << "HP:" << main.getHp() << endl << "att" << main.getAttack() << endl;
    int choice;
    cout << "You are attacked by a goblin!!!";

    cout <<"Goblin-"<< Goblin.getHealth()<<"hp"<<endl;
    do {
        cout << "choose an action" << endl << "1. Quick Attack" << endl << "2. Strong Attack" << endl << "3. Basic Attack";
        cin >> choice;
        Goblin.defendOutcome(choice, main.getAttack(), main.getDefense());
        if (Goblin.getHealth() > 0) {
            cout << Goblin.getHealth();
            cout << "choose an action" << endl << "1. Dodge" << endl << "2. Parry" << endl << "3. Block";
            cin >> choice;
            main.takeDamage(Goblin.attackOutcome(choice,main.getDefense()));
            cout << "Goblin-" << Goblin.getHealth() << "hp" << endl;
            cout << main.getName() << endl << "HP:" << main.getHp() << endl << "att" << main.getAttack() << endl;
        }
    } while (Goblin.getHealth() > 0 && main.getHp() > 0);
    if (Goblin.getHealth() > main.getHp()) cout << "you died!!!";
    else cout << "You won!!";
    cout << main.getHp();
    cin >> choice;
    return main;
}

//void mobList() {
    //same as items but for enemy NPCs
//}

Character.h

#pragma once
#include <string>
#include "Backpack.h"
#include "Item.h"
//The player class holds all the information for the player character in the story

//to-do:make stats more important 
using namespace std;

class Character
{
private:
    string charName; 
    enum statNames {Strength, Perception, Endurance, Charisma, Intelligence, Agility, Luck};//Player's stats effect many different things such as HP, Attack, and Defense
    int stats[8]; //array to hold the stats
    int level;//attack, HP, and Defense are all scaled according to level NOT YET IMPLEMENTED
    int maxHP, HP;//maxHP is determined by Endurance and Strength stats and level it is the maximum amount of HP the player can have, HP is the current health the player has.
    //include things such as speed which is based on agility, armor type, and stamina. base stamina depends on endurance, will be drained by weight of armor and weapon and actions.
    //same thing for power which is based on strength instead
    int baseAttack, attackBonus, totalAttack;//base attack is determined by strength, agility, and level. attackBonus is determined by items the player has equipped. totalAttack is baseAttack + bonusAttack and is the value used in combat
    int baseDefense, defenseBonus, totalDefense;//same as attack variables but baseDefense is based on strength and endurance
    Backpack playerInventory;//this is the player's inventory and is used to store and equip items. Equipped items can affect HP, maxHP, bonusAttack, and bonusDefense.


public:
    Character();
    ~Character();

    void characterCreation (int * playerStats , string playerName);//function used to take values from the main program when first creating character
    void lvlUp();//function used to increase stats,baseAttack,baseDefense, and maxHP when the player levels up

    //these are self-explanatory and used in the main function for different situations
    string getName() { return charName; }
    int getHp() { return HP; }
    int getAttack() { return totalAttack; };
    int getLevel() { return level; }
    int getDefense() { return totalDefense; }
    void takeDamage(int damageTaken) { HP = HP - damageTaken; };

    //all of these refer to the backpack class to handle playerInventory
    void addInv(Item newItem) { playerInventory.insert(newItem); };
    void showInv();
    void showEquipped() { playerInventory.showEquipped(); }; //BROKEN
};

character.cpp

#include "stdafx.h"
#include "Character.h"

Character::Character() {

}

Character::~Character() {

}


void Character::lvlUp() 
{

}

void Character::characterCreation(int *charStats, string name)
{
    charName = name;
    level = 1;
    for (int i = 0; i < 7; i++) {
        stats[i]=charStats[i];
    }
    baseAttack = (stats[Strength] + stats[Agility]/2);//strength is the main determining factor of attack while agility is second thus it is halved
    baseDefense = (stats[Strength] + stats[Endurance]/2);//endurance is the main determining factor of attack while strength is second thus it is halved
    maxHP = ((stats[Endurance] + stats[Strength]/2)*14);//endurance is the main determining factor of attack while strength is second thus it is halved
    HP = maxHP;
    attackBonus = 0;//nothing is equipped upon chacter creation thus bonus = 0
    totalAttack = baseAttack;
    totalDefense = baseDefense;
}


void Character::showInv()//runs the showInv function of the Backpack class-in this function the player has the opportunity to change which items are equipped so changes are made to attack/defenseBonus and totalAttack/Defense
{
    playerInventory.showInv();
    attackBonus = playerInventory.getAttBon();
    defenseBonus = playerInventory.getDefBon();
    totalAttack = attackBonus + baseAttack;
    totalDefense = defenseBonus + baseDefense;
}

mob.h

#pragma once
#include <iostream>
#include <cstdlib>
#include <string>
#include "Item.h"
#include "Backpack.h"
//clean up duties(finish as you work)/add in stats and there effects
using namespace std;


class Mob
{
private:
    string name;
    enum statNames { Strength, Perception, Endurance, Charisma, Intelligence, Agility, Luck };//Player's stats effect many different things such as HP, Attack, and Defense
    int stats[8]; //array to hold the stats
    int level;//attack, HP, and Defense are all scaled according to level
    int maxHP, HP;//maxHP is determined by Endurance and Strength stats and level it is the maximum amount of HP the player can have, HP is the current health the player has.
    int baseAttack, attackBonus, totalAttack;//base attack is determined by strength, agility, and level. attackBonus is determined by items the player has equipped. totalAttack is baseAttack + bonusAttack and is the value used in combat
    int baseDefense, defenseBonus, totalDefense;//same as attack variables but baseDefense is based on strength and endurance
    Backpack mobInventory;//this is the player's inventory and is used to store and equip items. Equipped items can affect HP, maxHP, bonusAttack, and bonusDefense.

public:
    Mob(int * mobStats, string mobName);
    ~Mob();
    int getHealth() { return HP; };
    int getAttack() { return totalAttack; };
    int getDefense() { return totalDefense; };
    void takeDamage(int dmg) { HP = HP - dmg; };
    void defendOutcome(int atkChoice, int attack, int def);
    int attackOutcome(int defChoice, int def);

    //all of these refer to the backpack class to handle mobInventory
    void addInv(Item newItem) { mobInventory.insert(newItem); mobEquip(); };
    void mobEquip() { mobInventory.mobInv(); 
    attackBonus = mobInventory.getAttBon();
    defenseBonus = mobInventory.getDefBon();
    totalAttack = attackBonus + baseAttack;
    totalDefense = defenseBonus + baseDefense;
    };
    void showEquipped() { mobInventory.showEquipped(); }; //BROKEN
    void showInv() { mobInventory.showInv(); }
};

mob.cpp

#include "stdafx.h"
#include "Mob.h"
#include <iostream>
#include <cstdlib>
#include <time.h>

using namespace std;

Mob::Mob(int * mobStats, string mobName)
{
    name = mobName;
    level = 1;
    for (int i = 0; i < 7; i++) {
        stats[i] = mobStats[i];
    }
    baseAttack = (stats[Strength] + stats[Agility] / 2);//strength is the main determining factor of attack while agility is second thus it is halved
    baseDefense = (stats[Strength] + stats[Endurance] / 2);//endurance is the main determining factor of attack while strength is second thus it is halved
    maxHP = ((stats[Endurance] + stats[Strength] / 2) * 14);//endurance is the main determining factor of attack while strength is second thus it is halved
    HP = maxHP;
    attackBonus = 0;//nothing is equipped upon chacter creation thus bonus = 0
    totalAttack = baseAttack;
    totalDefense = baseDefense;
}


Mob::~Mob()
{
}

void Mob::defendOutcome(int atkChoice, int atk, int def)//for this and attack make mob more likely to choose an action based on its own stats and weapon/armor-player character can detect what they might do based on perception.
//also make hit chance and modifiers dependent on pc and npc stats and equipment
{
    srand(time(0));
    int realDamage = 0;
    int damage = 0;
    int blockPenalty = 0;
    int hitChance = 0;
    double modifier = 0;
    int defChoice = rand()%3+1;
    cout << "THIS IS THE DEFENCE CHOICE ->" << defChoice<<endl;
    if (atkChoice == 1) {
        hitChance = 80;
            if (defChoice == 1) {
                modifier = 2;
                hitChance += 10;
                cout << name << " attempted to dodge your attack(q)\n";
            }
            else if (defChoice == 2) {
                modifier = 1;
                hitChance -= 50;
                cout << name << " attempted to parry your attack(q)\n";
            }
            else if (defChoice == 3) {
                modifier = 2.5;
                hitChance -= 45;
                blockPenalty = 10;
                cout << name << " attempted to block your attack(q)\n";
            }
    }
    else if (atkChoice == 2) {
        hitChance = 50;
        if (defChoice == 1) {
            modifier = 2.5;
            hitChance -= 30;
            cout << name << " attempted to dodge your attack(s)\n";
        }
        else if (defChoice == 2) {
            modifier = 4;
            hitChance += 40;
            cout << name << " attempted to parry your attack(s)\n";
        }
        else if (defChoice == 3) {
            modifier = 3;
            hitChance -= 45;
            blockPenalty = 20;
            cout << name << " attempted to block your attack(s)\n";
        }
    }
    else if (atkChoice == 3) {
        hitChance = 70;
        if (defChoice == 1) {
            modifier = 1;
            hitChance -= 10;
            cout << name << " attempted to dodge your attack(b)\n";
        }
        else if (defChoice == 2) {
            modifier = 1;
            hitChance -= 5;
            cout << name << " attempted to parry your attack(b)\n";
        }
        else if (defChoice == 3) {
            modifier = .5;
            hitChance -= 45;
            blockPenalty = atk/2;
            cout << name << " attempted to block your attack(b)\n";
        }
    }
    damage = atk * modifier + blockPenalty;
    int chanceVar = rand() % 100 + 1;
    cout << "ChanceVar: " << chanceVar << endl << "hitChance:" << hitChance << endl;
    if (chanceVar <= hitChance) {
        cout << "HP: " << HP << endl ;
        realDamage = damage - totalDefense;
        if (realDamage > 0) HP = HP - realDamage;
        cout << "success! You landed your attack for " << realDamage << " damage!\n";
    }
    else {
        realDamage = blockPenalty - totalDefense;
        if (realDamage > 0) HP = HP - realDamage;
        cout << "Your attack failed you only caused " << blockPenalty << " damage\n";
    }
}

int Mob::attackOutcome(int defChoice, int def)
{
    srand(time(0));
    int realDamage = 0;
    int damage = 0;
    int blockPenalty = 0;
    int hitChance = 50;
    double modifier = 1;
    int atkChoice = rand() % 3 + 1;
    cout << "THIS IS THE attack CHOICE ->" << atkChoice << endl;
    if (atkChoice == 1) {
        hitChance = 80;
        if (defChoice == 1) {
            modifier = 2;
            hitChance += 10;
            cout << name << " attempted quick attack(d)\n";
        }
        else if (defChoice == 2) {
            modifier = 1.5;
            hitChance -= 50;
            cout << name << " attempted quick attack(p)\n";
        }
        else if (defChoice == 3) {
            modifier = 1;
            hitChance -= 45;
            blockPenalty = 10;
            cout << name << " attempted quick attack(b)\n";
        }
    }
    else if (atkChoice == 2) {
        hitChance = 50;
        if (defChoice == 1) {
            modifier = 2.5;
            hitChance -= 30;
            cout << name << " attempted strong attack(d)\n";
        }
        else if (defChoice == 2) {
            modifier = 4;
            hitChance += 40;
            cout << name << " attempted strong attack(p)\n";
        }
        else if (defChoice == 3) {
            modifier = 1;
            hitChance -= 45;
            blockPenalty = 20;
            cout << name << " attempted strong attack(b)\n";
        }
    }
    else if (atkChoice == 3) {
        hitChance = 70;
        if (defChoice == 1) {
            modifier = 1;
            hitChance -= 10;
            cout << name << " attempted basic attack(d)\n";
        }
        else if (defChoice == 2) {
            modifier = 1;
            hitChance -= 5;
            cout << name << " attempted basic attack(p)\n";
        }
        else if (defChoice == 3) {
            modifier = .5;
            hitChance -= 45;
            blockPenalty = totalAttack/2;
            cout << name << " attempted basic attack(b)\n";
        }
    }
    damage = totalAttack * modifier + blockPenalty;
    int chanceVar = rand() % 100 + 1;
    cout << "THIS IS THE CHANCE VAR->" << chanceVar << endl;
    if (chanceVar <= hitChance) {
        realDamage = damage - totalDefense;
        cout << "failure! "<<name<<" landed attack for " << realDamage << " damage!\n";
        if (realDamage > 0) return realDamage;
        else return 0;
    }
    else {
        realDamage = blockPenalty - totalDefense;
        cout << "Succesful defense! "<< name <<" only caused " << realDamage << " damage\n";
        if (realDamage > 0) return realDamage;
        else return 0;
    }
}
s (27 sloc) 1.37 KB 

backpack.h

#pragma once
#include <string>
#include "item.h"
#include "Llist.h"
#include <iostream>

using namespace std;

class Backpack //used to store items for the player character and mobs, handle equipping the items, and looting from mobs
{
private:
    int GP;//amount of gold-main currency in game
    int attBon;//attack bonus from equipped items
    int defBon;//defense bonus from equipped items
    Item weapons[25];//array to hold a maximum of 25 weapon items
    Item armor[25];//array to hold a maximum of 25 armor items
    Item consumables[50];//array to hold a maximum of 50 consumable items
    Item equipped[2];//items equipped-only two slots right now slot 1 is for weapon slot 2 for armor
    void equip(Item itemToEquip);//function used to equip an item and apply its bonus(only accesible through showInv function)

public:
    Backpack();
    ~Backpack();
    void insert(Item newItem);//inserts item into the corrosponding Item array
    void showInv();//shows inventory and gives the option to equip items
    void showEquipped() { cout << "Weapon Slot:" << equipped[1]; cout << "Armor Slot:" << equipped[2]; }//displays currently equipped items-BROKEN
    int getAttBon() { return attBon; };//returns attack bonus to update player stats after equipping an item
    int getDefBon() { return defBon; };//returns defens bonus to update player stats after equipping an item
    void mobInv();//automatically equips best gear for mob
};

backpack.cpp

#include "stdafx.h"
#include "Backpack.h"
#include <iostream>

using namespace std;


Backpack::Backpack()//constructor
{   //creates an empty backpack filled with nullItem
    Item nullItem; 
    equipped[0] = nullItem;
    equipped[1] = nullItem;
    attBon = 0;
    for (int i = 0; i <= 25; i++) 
    {
        weapons[i] = nullItem;
        armor[i] = nullItem;
        consumables[i] = nullItem;
    }
    GP = 200;//starting gold for a new player
}


Backpack::~Backpack()
{
}

void Backpack::insert(Item newItem)//inserts an item into the next empty slot of the backpack
{
    int i = 0; //starts the search at the beggining of the list
    if (newItem.getid() < 2000 && newItem.getid() > 999) {
        Item nullItem;
        while (i <= 25) {
            if (weapons[i].getid() == 0) {//determines if the slot is empty --  if so, then an item is placed there and the search is terminated
                weapons[i] = newItem;
                weapons[i + 1] = nullItem;
                i = 25;
            }
            i++;//moves to the next slot if the slot wasn't empty
        }
    }
    if (newItem.getid() < 3000 && newItem.getid() > 1999) {
        Item nullItem;
        while (i <= 25) {
            if (armor[i].getid() == 0) {//determines if the slot is empty --  if so, then an item is placed there and the search is terminated
                armor[i] = newItem;
                armor[i + 1] = nullItem;
                i = 25;
            }
            i++;//moves to the next slot if the slot wasn't empty
        }
    }
}

void Backpack::showInv() //displays the inventory
{
    int choice;
    int exit = 1;
    do {
        int i = 0;
        cout << "Gold: " << GP << endl;
        cout << "equipped armor: " << equipped[0] << endl;
        cout << "equipped weapon: " << equipped[1] << endl;
        cout << "0. Exit\n1. Weapons\n2. Armor\n";
        cin >> choice;
        if (choice == 0) exit = 0;
        if (choice == 1) {
            do {
                cout << "____Weapons____" << endl;
                while (weapons[i].getid() != 0)
                {
                    cout << i + 1 << ": " << weapons[i] << endl;
                    i++;
                }
                cout << "To equip a weapon please press 1. To exit enter 0";
                cin >> choice;
                if (choice == 1)
                {
                    cout << "Please enter the corrosponding number of the weapon you want to equip";
                    cin >> choice;
                    equip(weapons[choice - 1]);
                }
            } while (choice != 0);
        }
        if (choice == 2) {
            do {
                cout << "____Armor____" << endl;
                while (armor[i].getid() != 0)
                {
                    cout << i + 1 << ": " << armor[i] << endl;
                    i++;
                }
                cout << "To equip armor please press 1. To exit enter 0";
                cin >> choice;
                if (choice == 1)
                {
                    cout << "Please enter the corrosponding number of the armor you want to equip";
                    cin >> choice;
                    equip(armor[choice - 1]);
                }
            } while (choice != 0);
        }
    } while (exit != 0);
}

void Backpack::equip(Item itemToEquip) 
{
    if (itemToEquip.getid() < 2000 && itemToEquip.getid() > 999) {
        equipped[1] = itemToEquip;
        attBon = itemToEquip.getAttBonItem();
        cout <<endl<< equipped[1] <<endl;
    }
    if (itemToEquip.getid() < 3000 && itemToEquip.getid() > 1999) {
        equipped[0] = itemToEquip;
        defBon = itemToEquip.getAttBonItem();
        cout << endl << equipped[0] << endl;
    }

}

void::Backpack::mobInv() { 
    Item itemToEquip = weapons[0]; //starts searching at the first item in the list
    int current = weapons[0].getAttBonItem(); //used to compare strength of the current weapon
    int compare; //checks if the strength of the next weapon is stronger than current
    int nullCheck = 1; //if the next weapon slot is empty it stops searching
    for (int i = 1; i <= 25; i++) { // run through the list to find the strongest weapon
        if (weapons[i].getid() == 0) nullCheck = 0;
        compare = weapons[i].getAttBonItem();
        if (current < compare && nullCheck != 0) { itemToEquip = weapons[i]; current = itemToEquip.getAttBonItem(); }
        if (weapons[i].getid() == 0) { i = 25; }
    }
    equip(itemToEquip);
    //do the same for armor
    itemToEquip = armor[0]; //starts searching at the first item in the list
    current = armor[0].getAttBonItem(); //used to compare strength of the current weapon
    compare; //checks if the strength of the next weapon is stronger than current
    nullCheck = 1; //if the next weapon slot is empty it stops searching
    for (int i = 1; i <= 25; i++) { // run through the list to find the strongest weapon
        if (armor[i].getid() == 0) nullCheck = 0;
        compare = armor[i].getAttBonItem();
        if (current < compare && nullCheck != 0) { itemToEquip = armor[i]; current = itemToEquip.getAttBonItem(); }
        if (armor[i].getid() == 0) { i = 25; }
    }
    equip(itemToEquip);
}

item.h

#pragma once
#include <string>
#include <iostream>

using namespace std;

class Item
{
private: //values each item can hold.
    int bonus; //amount of bonus an item provides (attack for weapong, defense for armor)
    int id; //used to find and store each individual item (number determines item type)
    int price; //how much gold item costs
    int weight; //how much weight item takes up in inventory
    string description; 
    string name;

public:
    Item();
    Item(int ID);
    Item(int ID, int w, int a, int p, string n);
    ~Item();

    //returns info about a specific item
    string getName() { return name; };
    int getPrice() { return price; };
    int getAttBonItem() { return bonus; };
    int getid() { return id; };

    //changes item values
    void setName(string a) { name = a; };
    void setPrice(int a) { price = a; };
    void setAttBon(int a) { bonus = a; };
    void setid(int a) { id = a; };

    //displays item details to console
    void display(ostream & out) {
        cout << name<<endl;
        cout <<"Price: "<< price<<endl;
        if (id < 2000 && id > 999) cout << "Damage: " << bonus << endl;
        if (id < 3000 && id > 1999) cout << "Defense: " << bonus << endl;
    }

    friend ostream & operator<<(ostream &out, Item & I);
};

inline ostream & operator<<(ostream &out, Item & I) { I.display(out); return out; }

item.cpp

#include "stdafx.h"
#include "Item.h"


Item::Item()//creates nullItem
{
    id = 0;
    weight = 0;
    price = 0;
    description = "None";
    bonus = 0;
    name = "Empty";
}

Item::Item(int ID) //creates an item with no stats
{
    id = ID;
    weight = 0;
    price = 0;
    description = "None";
    bonus = 0;
    name = "None";
}
Item::Item(int ID, int w,int a,int p,string n) //creates full item
{
    id = ID;
    weight = w;
    price = p;
    description = "NONE";
    bonus = a;
    name = n;
}



Item::~Item()
{
}
\$\endgroup\$
3
\$\begingroup\$

Some things that stand out:

  • You really ought to wrap your long comment lines as this is hard to read right now. Traditionally the line limit has been set at 80 (You might need an even lower one if you want your code to fit into the CR window).

  • #include "stdafx.h" is a Visual Studio specific thing meaning your code right now is not cross-platform compatible.

  • Sorting your headers would benefit readability. You could group them by local and external ones and then also sort them alphabetically.

  • A cardinal sin: Don't use using namespace std .

  • Why did you forward declare the functions in main?

  • In C++ & and * generally belong to the type. E.g. int* statPtr and not int * statPtr or int *statPtr.

  • Avoid empty destructors. Either leave it up to the compiler to generate them or declare them as default.

  • #pragma once is non-standard whereas include guards are.

  • Variable names such as w, a, p and n are not a good choice and hamper the understanding of your code.

  • Prefer using \n over std::endl.

  • Prefer prefix over postfix.

  • Order your interfaces from public to private so people can see the methods they can use without having to read through the internals.

  • When you initialize members you should either choose direct initialization or member initialization lists. You should also delegate your constructors instead of repeating everything.

  • Your operator<< is very interesting. It's a friend class to your Item class but doesn't access any internals. It simply calls a public member function and is not even making use of the passed stream argument. Calling the display function directly has the same effect.
    You probably meant to have something like this:

    inline ostream& operator<<(ostream& out, Item& obj) {
        out << obj.name << " Price: " << obj.price << "\n";
        // ...
        return out;
    }
    
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.