Class Errors with Pointers - c++

I'm currently writing a class for a program and this is what I'm attempting to accomplish...
Setup: Sets m_ptrEmployee to NULL and m_beginHour to hour.
AssignEmployee: Sets m_ptrEmployee to employee.
GetEmployeeName: Uses m_ptrEmployee and Employee.GetName to return the employees
name. Returns “UNALLOCATED”, if m_ptrEmployee is NULL.
Output: Uses m_ptrEmployee and Employee.GetName to display m_beginHour and the
employee’s name something like this, “8:00 - David Johnson” or like this, “8:00 -
UNALLOCATED”, if m_ptrEmployee is NULL.
Reset: Resets m_ptrEmployee to NULL.
GetIsSet: Returns true, if m_ptrEmployee is not NULL and false otherwise.
Here is my code...
#include <string>
using namespace std;
#include "Employee.h"
class Schedule
{
public:
void Setup( int hour )
{
m_ptrEmployee = NULL;
m_beginHour = hour;
};
void AssignEmployee( Employee* employee )
{
m_ptrEmployee = employee;
};
string GetEmployeeName()
{
if (m_ptrEmployee = NULL)
return "UNALLOCATED"
else
return Employee.GetName()
};
void Output()
{
if (m_ptrEmployee = NULL)
cout>> m_beginHour>>"--">>"UNALLOCATED">>endl;
else
cout>>m_beginHour>>"--">>GetName()>>endl;
}
void Reset()
{
m_ptrEmployee = NULL;
}
bool GetIsSet()
{
if (m_ptrEmployee != NULL)
return true;
else
return false;
}
private:
Employee* m_ptrEmployee;
int m_beginHour;
};
GetName() is included in a previous class and it is...
public:
void Setup( const string& first, const string& last, float pay );
{
m_firstName = first;
m_lastName = last;
m_payPerHour = pay;
m_activeEmployee = true;
}
string GetName()
{
return m_firstName+""+m_lastName
};
I'm receiving multiple errors and I'm not sure what I'm doing wrong? This is my first time attempting to write classes with pointers, so I apologize if my code is absolutely awful.

Here are some corrections:
In general, be careful with comparisons in C++. You can't use the intuitive = when comparing two things. You have to use ==. If you use =, it results in an assignment and not a test. Also, do not forget your semicolon ; at the end of a statement.
Bad comparison:
if (m_ptrEmployee = NULL) //Assigns NULL to m_ptrEmployee and then tests m_ptrEmployee
//Always false because m_ptrEmployee was just assigned NULL
Good comparison:
if (m_ptrEmployee == NULL) //Better. This is false only when m_ptrEmployee equals NULL
When you want to access a member of a class through a pointer (such as m_ptrEmployee), you have to use the -> operator like so: m_ptrEmployee->GetName()
Operator cout is used with the << operator, and not the >> operator.
I have annotated the places in your code where you made mistakes.
#include <string>
using namespace std;
#include "Employee.h"
class Schedule
{
public:
void Setup( int hour )
{
m_ptrEmployee = NULL;
m_beginHour = hour;
};
void AssignEmployee( Employee* employee )
{
m_ptrEmployee = employee;
};
string GetEmployeeName()
{
if (m_ptrEmployee == NULL) //Comparison always takes double ==
return "UNALLOCATED";
else
return m_ptrEmployee->GetName(); //Use employee pointer with -> operator
};
void Output()
{
if (m_ptrEmployee == NULL) //Careful with comparisons. Always use ==, not =
cout << m_beginHour << "--" << "UNALLOCATED" << endl; //Operator << was the other way around. It's not >>, but << for cout
else
cout << m_beginHour << "--" << m_ptrEmployee->GetName() << endl;
}
void Reset()
{
m_ptrEmployee = NULL;
}
bool GetIsSet()
{
if (m_ptrEmployee != NULL)
return true;
else
return false;
}
private:
Employee* m_ptrEmployee;
int m_beginHour;
};

Related

while loop in class won't execute c++

I have a while loop as part of a class.
#include <iostream>
#include <iomanip>
#include <fstream>
struct familyFinance{ //add 3rd member familyFinance;
int acctNos; float Balance; struct familyFinance *nextNodePointer;
struct familyFinance *dynMemory;
};
using namespace std;
class myFinanceClass {
private:
string fileName="";
familyFinance *ptrHead = nullptr;
public:
void setFileName(string){ fileName="Lab5Data.txt";}
void readFileAndBuildLinkedList(){
ifstream Lab3DataFileHandle;
familyFinance *ptrHead=nullptr;
//familyFinance *dynFinancePtr=nullptr;
familyFinance *tempPtr;
tempPtr=ptrHead;
Lab3DataFileHandle.open(fileName.c_str());
while (!Lab3DataFileHandle.eof( )) {
familyFinance *dynFinancePtr= new familyFinance;
Lab3DataFileHandle >> dynFinancePtr -> acctNos;
Lab3DataFileHandle >> dynFinancePtr -> Balance;
// familyFinance *nextNodePointer = nullptr;
if (ptrHead == nullptr) {
ptrHead = dynFinancePtr;
}
else {
tempPtr = ptrHead;
while (tempPtr -> nextNodePointer != nullptr )
tempPtr = tempPtr->nextNodePointer;
tempPtr->nextNodePointer = dynFinancePtr;
}
}
Lab3DataFileHandle.close();
}
void spitThemOut(){
familyFinance *tempNodePtr;
tempNodePtr = ptrHead;
Here is the While Loop
while (tempNodePtr) {
cout << "Acct, Balance: " << setw(3)
<<ptrHead->acctNos << " " <<ptrHead->Balance << endl;
tempNodePtr = tempNodePtr->nextNodePointer;
}
}
When I call the function from class in main I know it can read the function it just won't execute the while loop. What do I need to change to execute the while loop. It would be much apprenticed if you showed an example in your answer. Thank you for your time.
If the while loop is in the method and defined in that class, that won't execute, cause it's not allowed by the language. Methods defined within the class are not allowed to have any loops. There are a few more restrictions that apply for methods defined within the class. Such a case can be solved by declaring the method in the class but defining it outside the class as shown below
class myFinanceClass {
... // all the code before spitThemOut()
void spitThemOut();
};
void myFinanceClass::spitThemOut() {
... // code to work
while (tempNodePtr) {
...
}
}

Changing a value of an element in an object that is stored in a vector in another object through an external function in C++

So made a class called ‘Item’, and the object of that class will have a 100% condition at the start, the Player stores items (with name “apple” in this case) whenever I tell him to. In the degradeT function I want to pass the whole vector containing the items that the player has picked up by far and then change the condition of each Item in that vector by -1 through the chCond function.
first error:
initial value of reference to non-const must be an lvalue
second error:
'void degradeT(std::vector<Item,std::allocator<_Ty>> &)': cannot convert argument 1 from 'std::vector<Item,std::allocator<_Ty>>' to 'std::vector<Item,std::allocator<_Ty>> &'
#include "pch.h"
#include <iostream>
#include <string>
#include <vector>
using std::cout; using std::cin; using std::endl;
using std::string; using std::vector; using std::to_string;
class Item {
private:
string name; // Item name
float condition; // Item condition
bool consumable; // Is the item consumable
public:
Item() {}
Item(string a, float b, bool c) { name = a; condition = b; consumable = c; }
Item(string a, bool c) { name = a; condition = 100.f; consumable = c; }
string getName() {
return name;
}
float getCond() {
return condition;
}
bool isCons() {
return consumable;
}
void chCond(float a) { // Change Item condition
condition += a;
}
};
//-----------------------
class Player {
private:
vector<Item> plItems; // Item container
public:
Player() {}
void pickUpItem(Item a) { // Adding Items to inventory
plItems.push_back(a);
cout << a.getName() << " added to inventory!\n";
}
void checkItemConds() { // Checking condition of all items
for (unsigned int a = 0, siz = plItems.size(); a < siz; a++) {
cout << plItems[a].getName() << "'s condition is: " << plItems[a].getCond() << "%\n";
}
}
Item returnItem(unsigned int a) { // Return a specific Item
return plItems[a];
}
int getCurInvOcc() { // Get cuurent inventory occupation
return plItems.size();
}
vector<Item> getPlItems() { // Return the vector (Item container)
return plItems;
}
};
//-------------------------
void degradeT(vector<Item>& Itemss); // Degrade item after some time
//-------------------------
int main()
{
Player me; // me
string inp; // input
int num = 1; // apple 1, apple 2, apple 3...
while (inp != "exit") {
cin >> inp;
if (inp == "addApple") {
Item apple(("apple " + to_string(num)), true);
me.pickUpItem(apple);
num++;
}
if (inp == "checkItemConds") {
me.checkItemConds();
}
if (inp == "timeTick") {
// This doesn't have anything to do with time I just want to test the function manually
degradeT(me.getPlItems());
}
}
system("PAUSE");
return 0;
}
void degradeT(vector<Item> &Itemss) {
for (unsigned int a = 0, siz = Itemss.size(); a < siz; a++) {
Itemss[a].chCond(-1);
cout << Itemss[a].getName() << endl;
}
}
I'm not sure what your question is, but your error is related to the function void degradeT(vector<Item> & Itemss).
This functions expects a reference but you are passing an r-value. You can either return a reference with getPlItems() or pass an l-value to degradeT.

Header Guard Issues - Getting Swallowed Alive [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm totally at wit's end: I can't figure out how my dependency issues. I've read countless posts and blogs and reworked my code so many times that I can't even remember what almost worked and what didnt. I continually get not only redefinition errors, but class not defined errors. I rework the header guards and remove some errors simply to find others. I somehow got everything down to one error but then even that got broke while trying to fix it.
Would you please help me figure out the problem?
card.cpp
#include <iostream>
#include <cctype>
#include "card.h"
using namespace std;
// ====DECL======
Card::Card()
{
abilities = 0;
flavorText = 0;
keywords = 0;
artifact = 0;
classType = new char[strlen("Card") + 1];
classType = "Card";
}
Card::~Card (){
delete name;
delete abilities;
delete flavorText;
artifact = NULL;
}
// ------------
Card::Card(const Card & to_copy)
{
name = new char[strlen(to_copy.name) +1]; // creating dynamic array
strcpy(to_copy.name, name);
type = to_copy.type;
color = to_copy.color;
manaCost = to_copy.manaCost;
abilities = new char[strlen(to_copy.abilities) +1];
strcpy(abilities, to_copy.abilities);
flavorText = new char[strlen(to_copy.flavorText) +1];
strcpy(flavorText, to_copy.flavorText);
keywords = new char[strlen(to_copy.keywords) +1];
strcpy(keywords, to_copy.keywords);
inPlay = to_copy.inPlay;
tapped = to_copy.tapped;
enchanted = to_copy.enchanted;
cursed = to_copy.cursed;
if (to_copy.type != ARTIFACT)
artifact = to_copy.artifact;
}
// ====DECL=====
int Card::equipArtifact(Artifact* to_equip){
artifact = to_equip;
}
Artifact * Card::unequipArtifact(Card * unequip_from){
Artifact * to_remove = artifact;
artifact = NULL;
return to_remove;
// put card in hand or in graveyard
}
int Card::enchant( Card * to_enchant){
to_enchant->enchanted = true;
cout << "enchanted" << endl;
}
int Card::disenchant( Card * to_disenchant){
to_disenchant->enchanted = false;
cout << "Enchantment Removed" << endl;
}
// ========DECL=====
Spell::Spell()
{
currPower = basePower;
currToughness = baseToughness;
classType = new char[strlen("Spell") + 1];
classType = "Spell";
}
Spell::~Spell(){}
// ---------------
Spell::Spell(const Spell & to_copy){
currPower = to_copy.currPower;
basePower = to_copy.basePower;
currToughness = to_copy.currToughness;
baseToughness = to_copy.baseToughness;
}
// =========
int Spell::attack( Spell *& blocker ){
blocker->currToughness -= currPower;
currToughness -= blocker->currToughness;
}
//==========
int Spell::counter (Spell *& to_counter){
cout << to_counter->name << " was countered by " << name << endl;
}
// ============
int Spell::heal (Spell *& to_heal, int amountOfHealth){
to_heal->currToughness += amountOfHealth;
}
// -------
Creature::Creature(){
summoningSick = true;
}
// =====DECL======
Land::Land(){
color = NON;
classType = new char[strlen("Land") + 1];
classType = "Land";
}
// ------
int Land::generateMana(int mana){
// ... //
}
card.h
#ifndef CARD_H
#define CARD_H
#include <cctype>
#include <iostream>
#include "conception.h"
class Artifact;
class Spell;
class Card : public Conception
{
public:
Card();
Card(const Card &);
~Card();
protected:
char* name;
enum CardType { INSTANT, CREATURE, LAND, ENCHANTMENT, ARTIFACT, PLANESWALKER};
enum CardColor { WHITE, BLUE, BLACK, RED, GREEN, NON };
CardType type;
CardColor color;
int manaCost;
char* abilities;
char* flavorText;
char* keywords;
bool inPlay;
bool tapped;
bool cursed;
bool enchanted;
Artifact* artifact;
virtual int enchant( Card * );
virtual int disenchant (Card * );
virtual int equipArtifact( Artifact* );
virtual Artifact* unequipArtifact(Card * );
};
// ------------
class Spell: public Card
{
public:
Spell();
~Spell();
Spell(const Spell &);
protected:
virtual int heal( Spell *&, int );
virtual int attack( Spell *& );
virtual int counter( Spell*& );
int currToughness;
int baseToughness;
int currPower;
int basePower;
};
class Land: public Card
{
public:
Land();
~Land();
protected:
virtual int generateMana(int);
};
class Forest: public Land
{
public:
Forest();
~Forest();
protected:
int generateMana();
};
class Creature: public Spell
{
public:
Creature();
~Creature();
protected:
bool summoningSick;
};
class Sorcery: public Spell
{
public:
Sorcery();
~Sorcery();
protected:
};
#endif
conception.h -- this is an "uber class" from which everything derives
class Conception{
public:
Conception();
~Conception();
protected:
char* classType;
};
conception.cpp
Conception::Conception{
Conception(){
classType = new char[11];
char = "Conception";
}
game.cpp -- this is an incomplete class as of this code
#include <iostream>
#include <cctype>
#include "game.h"
#include "player.h"
Battlefield::Battlefield(){
card = 0;
}
Battlefield::~Battlefield(){
delete card;
}
Battlefield::Battlefield(const Battlefield & to_copy){
}
// ===========
/*
class Game(){
public:
Game();
~Game();
protected:
Player** player; // for multiple players
Battlefield* root; // for battlefield
getPlayerMove(); // ask player what to do
addToBattlefield();
removeFromBattlefield();
sendAttack();
}
*/
#endif
game.h
#ifndef GAME_H
#define GAME_H
#include "list.h"
class CardList();
class Battlefield : CardList{
public:
Battlefield();
~Battlefield();
protected:
Card* card; // make an array
};
class Game : Conception{
public:
Game();
~Game();
protected:
Player** player; // for multiple players
Battlefield* root; // for battlefield
getPlayerMove(); // ask player what to do
addToBattlefield();
removeFromBattlefield();
sendAttack();
Battlefield* field;
};
list.cpp
#include <iostream>
#include <cctype>
#include "list.h"
// ==========
LinkedList::LinkedList(){
root = new Node;
classType = new char[strlen("LinkedList") + 1];
classType = "LinkedList";
};
LinkedList::~LinkedList(){
delete root;
}
LinkedList::LinkedList(const LinkedList & obj)
{
// code to copy
}
// ---------
// =========
int LinkedList::delete_all(Node* root){
if (root = 0)
return 0;
delete_all(root->next);
root = 0;
}
int LinkedList::add( Conception*& is){
if (root == 0){
root = new Node;
root->next = 0;
}
else
{
Node * curr = root;
root = new Node;
root->next=curr;
root->it = is;
}
}
int LinkedList::remove(Node * root, Node * prev, Conception* is){
if (root = 0)
return -1;
if (root->it == is){
root->next = root->next;
return 0;
}
remove(root->next, root, is);
return 0;
}
Conception* LinkedList::find(Node*& root, const Conception* is, Conception* holder = NULL)
{
if (root==0)
return NULL;
if (root->it == is){
return root-> it;
}
holder = find(root->next, is);
return holder;
}
Node* LinkedList::goForward(Node * root){
if (root==0)
return root;
if (root->next == 0)
return root;
else
return root->next;
}
// ============
Node* LinkedList::goBackward(Node * root){
root = root->prev;
}
list.h
#ifndef LIST_H
#define LIST_H
#include <iostream>
#include "conception.h"
class Node : public Conception {
public:
Node() : next(0), prev(0), it(0)
{ it = 0;
classType = new char[strlen("Node") + 1];
classType = "Node";
};
~Node(){
delete it;
delete next;
delete prev;
}
Node* next;
Node* prev;
Conception* it; // generic object
};
// ----------------------
class LinkedList : public Conception {
public:
LinkedList();
~LinkedList();
LinkedList(const LinkedList&);
friend bool operator== (Conception& thing_1, Conception& thing_2 );
protected:
virtual int delete_all(Node*);
virtual int add( Conception*& ); //
virtual Conception* find(Node *&, const Conception*, Conception* ); //
virtual int remove( Node *, Node *, Conception* ); // removes question with keyword int display_all(node*& );
virtual Node* goForward(Node *);
virtual Node* goBackward(Node *);
Node* root;
// write copy constrcutor
};
// =============
class CircularLinkedList : public LinkedList {
public:
// CircularLinkedList();
// ~CircularLinkedList();
// CircularLinkedList(const CircularLinkedList &);
};
class DoubleLinkedList : public LinkedList {
public:
// DoubleLinkedList();
// ~DoubleLinkedList();
// DoubleLinkedList(const DoubleLinkedList &);
protected:
};
// END OF LIST Hierarchy
#endif
player.cpp
#include <iostream>
#include "player.h"
#include "list.h"
using namespace std;
Library::Library(){
root = 0;
}
Library::~Library(){
delete card;
}
// ====DECL=========
Player::~Player(){
delete fname;
delete lname;
delete deck;
}
Wizard::~Wizard(){
delete mana;
delete rootL;
delete rootH;
}
// =====Player======
void Player::changeName(const char[] first, const char[] last){
char* backup1 = new char[strlen(fname) + 1];
strcpy(backup1, fname);
char* backup2 = new char[strlen(lname) + 1];
strcpy(backup1, lname);
if (first != NULL){
fname = new char[strlen(first) +1];
strcpy(fname, first);
}
if (last != NULL){
lname = new char[strlen(last) +1];
strcpy(lname, last);
}
return 0;
}
// ==========
void Player::seeStats(Stats*& to_put){
to_put->wins = stats->wins;
to_put->losses = stats->losses;
to_put->winRatio = stats->winRatio;
}
// ----------
void Player::displayDeck(const LinkedList* deck){
}
// ================
void CardList::findCard(Node* root, int id, NodeCard*& is){
if (root == NULL)
return;
if (root->it.id == id){
copyCard(root->it, is);
return;
}
else
findCard(root->next, id, is);
}
// --------
void CardList::deleteAll(Node* root){
if (root == NULL)
return;
deleteAll(root->next);
root->next = NULL;
}
// ---------
void CardList::removeCard(Node* root, int id){
if (root == NULL)
return;
if (root->id = id){
root->prev->next = root->next; // the prev link of root, looks back to next of prev node, and sets to where root next is pointing
}
return;
}
// ---------
void CardList::addCard(Card* to_add){
if (!root){
root = new Node;
root->next = NULL;
root->prev = NULL;
root->it = &to_add;
return;
}
else
{
Node* original = root;
root = new Node;
root->next = original;
root->prev = NULL;
original->prev = root;
}
}
// -----------
void CardList::displayAll(Node*& root){
if (root == NULL)
return;
cout << "Card Name: " << root->it.cardName;
cout << " || Type: " << root->it.type << endl;
cout << " --------------- " << endl;
if (root->classType == "Spell"){
cout << "Base Power: " << root->it.basePower;
cout << " || Current Power: " << root->it.currPower << endl;
cout << "Base Toughness: " << root->it.baseToughness;
cout << " || Current Toughness: " << root->it.currToughness << endl;
}
cout << "Card Type: " << root->it.currPower;
cout << " || Card Color: " << root->it.color << endl;
cout << "Mana Cost" << root->it.manaCost << endl;
cout << "Keywords: " << root->it.keywords << endl;
cout << "Flavor Text: " << root->it.flavorText << endl;
cout << " ----- Class Type: " << root->it.classType << " || ID: " << root->it.id << " ----- " << endl;
cout << " ******************************************" << endl;
cout << endl;
// -------
void CardList::copyCard(const Card& to_get, Card& put_to){
put_to.type = to_get.type;
put_to.color = to_get.color;
put_to.manaCost = to_get.manaCost;
put_to.inPlay = to_get.inPlay;
put_to.tapped = to_get.tapped;
put_to.class = to_get.class;
put_to.id = to_get.id;
put_to.enchanted = to_get.enchanted;
put_to.artifact = to_get.artifact;
put_to.class = to_get.class;
put.to.abilities = new char[strlen(to_get.abilities) +1];
strcpy(put_to.abilities, to_get.abilities);
put.to.keywords = new char[strlen(to_get.keywords) +1];
strcpy(put_to.keywords, to_get.keywords);
put.to.flavorText = new char[strlen(to_get.flavorText) +1];
strcpy(put_to.flavorText, to_get.flavorText);
if (to_get.class = "Spell"){
put_to.baseToughness = to_get.baseToughness;
put_to.basePower = to_get.basePower;
put_to.currToughness = to_get.currToughness;
put_to.currPower = to_get.currPower;
}
}
// ----------
player.h
#ifndef player.h
#define player.h
#include "list.h"
// ============
class CardList() : public LinkedList(){
public:
CardList();
~CardList();
protected:
virtual void findCard(Card&);
virtual void addCard(Card* );
virtual void removeCard(Node* root, int id);
virtual void deleteAll();
virtual void displayAll();
virtual void copyCard(const Conception*, Node*&);
Node* root;
}
// ---------
class Library() : public CardList(){
public:
Library();
~Library();
protected:
Card* card;
int numCards;
findCard(Card&); // get Card and fill empty template
}
// -----------
class Deck() : public CardList(){
public:
Deck();
~Deck();
protected:
enum deckColor { WHITE, BLUE, BLACK, RED, GREEN, MIXED };
char* deckName;
}
// ===============
class Mana(int amount) : public Conception {
public:
Mana() : displayTotal(0), classType(0)
{ displayTotal = 0;
classType = new char[strlen("Mana") + 1];
classType = "Mana";
};
protected:
int accrued;
void add();
void remove();
int displayTotal();
}
inline Mana::add(){ accrued += 1; }
inline Mana::remove(){ accrued -= 1; }
inline Mana::displayTotal(){ return accrued; }
// ================
class Stats() : public Conception {
public:
friend class Player;
friend class Game;
Stats() : wins(0), losses(0), winRatio(0) {
wins = 0; losses = 0;
if ( (wins + losses != 0)
winRatio = wins / (wins + losses);
else
winRatio = 0;
classType = new char[strlen("Stats") + 1];
classType = "Stats";
}
protected:
int wins;
int losses;
float winRatio;
void int getStats(Stats*& );
}
// ==================
class Player() : public Conception{
public:
Player() : wins(0), losses(0), winRatio(0) {
fname = NULL;
lname = NULL;
stats = NULL;
CardList = NULL;
classType = new char[strlen("Player") + 1];
classType = "Player";
};
~Player();
Player(const Player & obj);
protected:
// member variables
char* fname;
char* lname;
Stats stats; // holds previous game statistics
CardList* deck[]; // hold multiple decks that player might use - put ll in this
private:
// member functions
void changeName(const char[], const char[]);
void shuffleDeck(int);
void seeStats(Stats*& );
void displayDeck(int);
chooseDeck();
}
// --------------------
class Wizard(Card) : public Player(){
public:
Wizard() : { mana = NULL; rootL = NULL; rootH = NULL};
~Wizard();
protected:
playCard(const Card &);
removeCard(Card &);
attackWithCard(Card &);
enchantWithCard(Card &);
disenchantWithCard(Card &);
healWithCard(Card &);
equipWithCard(Card &);
Mana* mana[];
Library* rootL; // Library
Library* rootH; // Hand
}
#endif
At least one of your problems is that in "player.h" you have
#ifndef player.h
#define player.h
"player.h" is not a legal pre-processor symbol. Did you mean
#ifndef player_h
#define player_h
?
Secondly, conception.cpp doesn't #include anything.
Third, your class definitions are largely invalid.
class Foo()
is not legal, nor is
class Foo() : public class Bar()
What does '()' have to do with a class name? Are you thinking of the constructor?
Then there is this
char = "Conception";
You can't assign a value to a type.
----- Feedback to help you clean up the code -----
. Choose a style
Or - if you are working with someone else's code, take theirs.
But stick with it.
A huge percentage of software defects that make it past initial development are there because they were hard to spot - missing semi-colons, missing {s around compound statements, etc. C.f. "CARD_H" vs "player.h".
. Inconsistency is the mother of most bugs
classType = new char[11];
char = "Conception";
You probably mean
classType = new char[11];
classType = "Conception";
but this is a memory leak and a bug waiting to happen. In Card:: you do it more correctly
name = new char[strlen(to_copy.name) +1]; // creating dynamic array
strcpy(to_copy.name, name);
The version you use elsewhere
classType = new ...
classType = "String";
allocates some memory, stores the address in classType. Then it looks up the variable of the compiled char* array "String\0" and stores it's address in classType instead.
When the class goes away, it will try to delete the static string and crash.
If this is a learning exercise and you're trying to learn about memory management, this general approach may be fair enough. But placing ownership of pointers in your classes like this is a sure-fire way to wind up with memory leaks and undefined behavior bugs.
It's best to encapsulate pointers in an RAII-style class (a class which owns the pointer and does the delete when it goes out of scope). Take a look into "std::unique_ptr", "std::shared_ptr" and "std::weak_ptr". For your purposes, "std::string" may help you reduce the number of defects by eliminating a lot of the managerial overhead.
. Try to avoid mixing initializer lists with assignment lists.
It's generally better to use one or the other. You can probably get away with using initializer lists when all of your members can be initialized that way, but if they can't, it may be better to use assignment.
Foo() : m_a(), m_b(), m_c() { m_b = 1; m_c = 2; } // is m_a not having a value a bug or intentional?
. Distinguish member variables from ordinary variables.
You're going to run into bugs where values dissapear on you as a result of shadowing: Shadowing variables
#include <iostream>
int i = 0;
int main() {
int i = 1;
for (int i = 0; i < 10; ++i) {
int i = 2 * i;
std::cout << i << std::endl;
}
return 0;
}
when you don't distinguish your member variables (a lot of people use an "m_" prefix, others use a "_" suffix) this is GOING to happen to you frequently.
. Don't assign numeric values to pointers.
name = 0;
while this compiles, you're setting yourself up for less obvious cases appearing to be numbers and Bad Things Ensuing.
abilities = 0;
No, I'm superman, I have ALL the abilities.
abilities = 42;
Two more correct ways to do this would be
name = NULL; // Traditional C++
or
name = nullptr; // C++11
You've done this in someplaces, again consistency is failing you.
. (minor but it'll bite you in the ass in a few weeks) "it" is generally used to reference an "iterator", you might want to use "data" or "value" or "element".
. avoid making members of classes/objects public.
Your "Node" class looks incredibly buggy (the destructor deletes both prev and next???) and you can't tell, from looking at the class, how the "it" pointer gets set, presumably because that happens elsewhere. Where else do you tamper with the "it", prev and next pointers? Encapsulate.
. 'const' can be your friend (by being a pain in your ass)
if (to_get.class = "Spell"){
This will assign "Spell" to to_get.class, causing a memory leak and other issues, and then succeed -- "Spell" evaluates to a fixed const char* address, which is non-zero, which is therefore true.
(It also doesn't compile because 'class' is a keyword and the actual variable is 'className').
You can prevent this by protecting your actual members and only exposing them thru carefully chosen accessors.
const char* Class() const { return m_className; }
Let me break this one down:
const char* :- you cannot modify the contents,
Class() :- instead of to_get.class you'll use to_get.Class()
const :- this function does not have side-effects on the object
The last part means that it can be used on a const object.
class Beer {
bool m_isFull;
public:
Beer() : m_isFull(true) {}
// non-const function, has side-effects (changes isFull);
void drink() { m_isFull = false; }
// const function, returns a copy of "m_isFull". you can
// change the value that's returned, but it doesn't affect us.
void isFull() const { return m_isFull; }
// example of a non-const accessor, if you REALLY want
// the caller to be able to modify m_isFull for some reason.
const bool& getIsFull() { return m_isFull; }
};
. Lastly: Learn to isolate concepts and algorithms.
A lot of the mistakes/bugs/errors in the code appear to be because you're not 100% with some of the nuances or even details. That's not unreasonable, but you need to find a way to be able to try out the little bits of the language.
Take a little time to learn to roll out micro-programs on something like ideone.com. If you are using Linux, make yourself a "srctest" directory with a "test.cpp" and "test.h" and a Makefile
Makefile
all: srctest
srctest: srctest.cpp srctestextern.cpp srctest.h
g++ -o srctest -Wall -ggdb srctest.cpp srctestextern.cpp
srctest.cpp
#include "srctest.h"
#include <iostream>
// add your other includes here and just leave them.
int main() {
return 0;
}
srctest.h
#ifndef SRCTEST_SRCTEST_H
#define SRCTEST_SRCTEST_H
// anything I want to test in a .h file here
#endif
srctestextern.cpp
#include "srctest.h"
// Anything you want to test having in a separate source file goes here.
If you're using visual studio, set yourself up something similar.
The idea is to have somewhere you can go and drop in a few lines of code and be comfortable stepping thru what you're trying in a debugger.
Being able to quickly localize problems is a key part of being a successful programmer as opposed to being an employed code monkey.

How do you display particular nodes in a Linked List?

I'm am fairly new to C++.
I have this code from an assignment, i don't quite understand all of it, but i have to make the program give an option at the end for the user to recall any partnumber and model year/engine no. that was entered.
I have no idea on how to go about doing this task... maybe have some kind of id for each node so i can recall it?
Or is it my only option to rewrite the program using an array or vector data structure?
#include <iostream>
using namespace std;
typedef unsigned long ULONG;
typedef unsigned short USHORT;
// **************** Part ************
// Abstract base class of parts
class Part
{
friend void showPart();
public:
Part():itsPartNumber(1) {}
Part(ULONG PartNumber):itsPartNumber(PartNumber){}
virtual ~Part(){};
ULONG GetPartNumber() const { return itsPartNumber; }
virtual void Display() const =0; // must be overridden
private:
ULONG itsPartNumber;
};
// implementation of pure virtual function so that
// derived classes can chain up
void Part::Display() const
{
cout << "\nPart Number: " << itsPartNumber << endl;
}
// **************** Car Part ************
class CarPart : public Part
{
friend void showPart();
public:
CarPart():itsModelYear(94){}
CarPart(USHORT year, ULONG partNumber);
virtual void Display() const
{
Part::Display(); cout << "Model Year: ";
cout << itsModelYear << endl;
}
private:
USHORT itsModelYear;
};
CarPart::CarPart(USHORT year, ULONG partNumber):
itsModelYear(year),
Part(partNumber)
{}
// **************** AirPlane Part ************
class AirPlanePart : public Part
{
friend void showPart();
public:
AirPlanePart():itsEngineNumber(1){};
AirPlanePart(USHORT EngineNumber, ULONG PartNumber);
virtual void Display() const
{
Part::Display(); cout << "Engine No.: ";
cout << itsEngineNumber << endl;
}
private:
USHORT itsEngineNumber;
};
AirPlanePart::AirPlanePart(USHORT EngineNumber, ULONG PartNumber):
itsEngineNumber(EngineNumber),
Part(PartNumber)
{}
// **************** Part Node ************
class PartNode
{
public:
PartNode (Part*);
~PartNode();
void SetNext(PartNode * node) { itsNext = node; }
PartNode * GetNext() const;
Part * GetPart() const;
private:
Part *itsPart;
PartNode * itsNext;
};
// PartNode Implementations...
PartNode::PartNode(Part* pPart):
itsPart(pPart),
itsNext(0)
{}
PartNode::~PartNode()
{
delete itsPart;
itsPart = 0;
delete itsNext;
itsNext = 0;
}
// Returns NULL if no next PartNode
PartNode * PartNode::GetNext() const
{
return itsNext;
}
Part * PartNode::GetPart() const
{
if (itsPart)
return itsPart;
else
return NULL; //error
}
// **************** Part List ************
class PartsList
{
public:
PartsList();
~PartsList();
// needs copy constructor and operator equals!
Part* Find(ULONG & position, ULONG PartNumber) const;
ULONG GetCount() const { return itsCount; }
Part* GetFirst() const;
static PartsList& GetGlobalPartsList()
{
return GlobalPartsList;
}
void Insert(Part *);
void Iterate(void (Part::*f)()const) const;
Part* operator[](ULONG) const;
private:
PartNode * pHead;
ULONG itsCount;
static PartsList GlobalPartsList;
};
PartsList PartsList::GlobalPartsList;
// Implementations for Lists...
PartsList::PartsList():
pHead(0),
itsCount(0)
{}
PartsList::~PartsList()
{
delete pHead;
}
Part* PartsList::GetFirst() const
{
if (pHead)
return pHead->GetPart();
else
return NULL; // error catch here
}
Part * PartsList::operator[](ULONG offSet) const
{
PartNode* pNode = pHead;
if (!pHead)
return NULL; // error catch here
if (offSet > itsCount)
return NULL; // error
for (ULONG i=0;i<offSet; i++)
pNode = pNode->GetNext();
return pNode->GetPart();
}
Part* PartsList::Find(ULONG & position, ULONG PartNumber) const
{
PartNode * pNode = 0;
for (pNode = pHead, position = 0;
pNode!=NULL;
pNode = pNode->GetNext(), position++)
{
if (pNode->GetPart()->GetPartNumber() == PartNumber)
break;
}
if (pNode == NULL)
return NULL;
else
return pNode->GetPart();
}
void PartsList::Iterate(void (Part::*func)()const) const
{
if (!pHead)
return;
PartNode* pNode = pHead;
do
(pNode->GetPart()->*func)();
while (pNode = pNode->GetNext());
}
void PartsList::Insert(Part* pPart)
{
PartNode * pNode = new PartNode(pPart);
PartNode * pCurrent = pHead;
PartNode * pNext = 0;
ULONG New = pPart->GetPartNumber();
ULONG Next = 0;
itsCount++;
if (!pHead)
{
pHead = pNode;
return;
}
// if this one is smaller than head
// this one is the new head
if (pHead->GetPart()->GetPartNumber() > New)
{
pNode->SetNext(pHead);
pHead = pNode;
return;
}
for (;;)
{
// if there is no next, append this new one
if (!pCurrent->GetNext())
{
pCurrent->SetNext(pNode);
return;
}
// if this goes after this one and before the next
// then insert it here, otherwise get the next
pNext = pCurrent->GetNext();
Next = pNext->GetPart()->GetPartNumber();
if (Next > New)
{
pCurrent->SetNext(pNode);
pNode->SetNext(pNext);
return;
}
pCurrent = pNext;
}
}
int main()
{
PartsList pl = PartsList::GetGlobalPartsList();
Part * pPart = 0;
ULONG PartNumber;
USHORT value;
ULONG choice;
while (1)
{
cout << "(0)Quit (1)Car (2)Plane: ";
cin >> choice;
if (!choice)
break;
cout << "New PartNumber?: ";
cin >> PartNumber;
if (choice == 1)
{
cout << "Model Year?: ";
cin >> value;
pPart = new CarPart(value,PartNumber);
}
else
{
cout << "Engine Number?: ";
cin >> value;
pPart = new AirPlanePart(value,PartNumber);
}
pl.Insert(pPart);
}
void (Part::*pFunc)()const = &Part::Display;
pl.Iterate(pFunc);
cout << "\n\n\nThere are " << pl.GetCount() << " items in the list" << endl;
return 0;
}
I tried using The Find() in the PartsList class. Does Find() take the partnumber and return the address of the part?
I wrote this to dereference the retrieved address, but it gives me the error no match for 'operator<<' in 'std::cout << * show':
int findnumber;
ULONG position;
cout << "Enter Partnumber" << endl;
cin >> findnumber;
Part* show = pl.Find(position, findnumber);
cout << *show;
Am i doing this all wrong? D: Show me please...
The function Find does take a part number, but returns a pointer to a part, which is not the same as the address of the part (that would be a reference, denoted by an &). In addition, Find takes a reference to a variable called 'position', so after calling the Find function, the variable that was passed in for 'position' will contain the value of where the part is in the linked list.
The reason you can't use the << operator, is that it hasn't been provided for the Part class. However, from the source code provided, it looks like the objective is for you to understand Polymorphism and rather than trying to use <<, call the Display function on the part that you have found. e.g: -
Part* part = pl.Find(position, findnumber);
part->Display();
This will display the text for the relevant type of part, so if the part returned was a CarPart, the CarPart's Display function will be called, whereas if the part is an AirPlane part, its Display function is called.
If you wanted to use the stream operator (<<) you'd need to overload the io operators, which you can read more about here.
The class PartsList already has a Find() method that could be used to retrieve any part based on its partnumber. You can then call the Display() method of that part.

C++ error LNK2019 && fatal error LNK1120: 1 unresolved externals

I am trying to work on a homework assignment for school and am going above what the teacher is asking for the assignment -> I have created a "list" class. I keep running into these two errors after adding the 'add()' method to the program - along with the 'newIncomeTax()' methods
error LNK2019: unresolved external symbol "public: void __thiscall List::add(class IncomeTax *)" (?add#List##QAEXPAVIncomeTax###Z) referenced in function _main driver.obj
and
fatal error LNK1120: 1 unresolved externals
I hope this will be enough code for anyone trying to help me:
note: the functions below are not in the order that they appear in the original code
(if that may be the problem I can provide all the code that i'm using)
list.h
#ifndef LIST_H
#define LIST_H
#include "IncomeTax.h"
class List
{
private:
IncomeTax * First;
IncomeTax * Last;
int num_in_list;
public:
List () { num_in_list = 0; First = NULL; Last = NULL; }
int get_num_in_list() { return num_in_list; }
IncomeTax * getFirst() { return First; }
IncomeTax * getLast() { return Last; }
void del_frnt ();
void push_front (IncomeTax *);
void push_back (IncomeTax *);
void del_last ();
void add (IncomeTax*);
IncomeTax * pop_back ();
IncomeTax * pop_front ();
IncomeTax * get (int);
};
#endif
note: from what I've seen the list that **I've** made behaves similarly to the default
the 'add' method from list.cpp
void List:: add (IncomeTax * IncomeTax_to_be_added) {
if (num_in_list == 0) { First = IncomeTax_to_be_added; Last = IncomeTax_to_be_added; }
else if (num_in_list != 0 ) {
Last->setNext(IncomeTax_to_be_added);
IncomeTax_to_be_added->setPrevous(Last);
Last = IncomeTax_to_be_added;
}
num_in_list++;
}
IncomeTax.h
#ifndef INCOME_TAX
#define INCOME_TAX
#include <iostream>
#include <string>
#include "conio.h"
#include <cassert>
using namespace std;
class IncomeTax {
private:
double incm;
double ajIncm;
double subtract;
double taxRate;
double add;
bool married;
void calcIncome_m ();
void calcIncome_s ();
public:
IncomeTax () { incm = 0; subtract = 0; taxRate = 0; add = 0; add = false; }
// married -> is by default false
void setmarried ( bool stats ) { married = stats; }
void setIncm (double in ) { incm = in; }
void setSubtract ( double sub ) { subtract = sub; }
void setTaxRate ( double rate ) { taxRate = rate; }
void setAdd ( double Add ) { add = Add; }
void setAjIncome ( double AJincome ) { ajIncm = AJincome; }
bool getmarried () { return married; }
double getIncm () { return incm; }
double getsubtract () { return subtract; }
double getTaxRate () { return taxRate; }
double getAdd () { return add; }
double getAJincome () { return ajIncm; }
void calcIncome ();
void pintIncome ();
};
#endif
IncomeTax.cpp
#include "IncomeTax.h"
using namespace std;
void IncomeTax::calcIncome(){
assert (incm != 0);
if (married) { calcIncome_m(); }
if (!married) { calcIncome_s(); }
ajIncm = (incm - subtract);
ajIncm -= (ajIncm * taxRate);
ajIncm += add;
}
void IncomeTax::calcIncome_m() {
assert (incm != 0);
... huge nested if statements ...
they set subtract, add, taxRate...
}
void IncomeTax::calcIncome_s() {
assert (incm != 0);
... huge nested if statements ...
they set subtract, add, taxRate...
}
void IncomeTax::pintIncome () {
assert (incm != 0);
assert (ajIncm != 0);
std::cout.precision(2);
cout << "\tTaxable Income: " << incm << endl;
cout << "\tAjusted Income: " << ajIncm << endl;
cout << "\tTax: " << (incm - ajIncm) << "\n" << endl;
}
Driver.cpp
#include <conio.h>
#include <iostream>
#include <string>
#include <cassert>
#include "IncomeTax.h"
#include "List.h"
using namespace std;
void getMaritalStatus( IncomeTax new_tax) {
bool done = false;
char stt = ' ';
while ( !done ) {
cout << "\nPlease declare weather you are filing taxes jointly or single" << "\n";
cout << "\t's' = single\n\t'm' = married" << endl;
stt = getch();
if ( stt == 's' || stt == 'm' ) { done = true; }
if ( stt == 's' ) { new_tax.setmarried(true); }
if ( ! (stt == 's' || stt == 'm') ) { cout << "\nyou have entered an invald symbol... \n" << endl; }
if(cin.fail()) { cin.clear(); }
}
}
void get_Income ( IncomeTax new_tax) {
double _incm = 0;
char status = ' ';
bool done = true;
while ( done ) {
cout << "Please enter your TAXABLE INCOME:" << endl;
cin >> _incm;
if ( _incm > 0 ) { new_tax.setIncm(_incm); done = false; }
if ( _incm <= 0 ) { cout << "\nthe number you entered was less than zero\nplease enter a valad number...\n" << endl; }
if(cin.fail()) { cin.clear(); }
}
}
IncomeTax newIncomeTax () {
IncomeTax new_tax;
IncomeTax * temp;
get_Income(new_tax);
getMaritalStatus(new_tax);
new_tax.calcIncome();
return new_tax;
}
bool again () {
bool done = false, answer = false;
char yn = ' ';
while ( !done ) {
cout << "\nWould you like to calculate another Income tax? (y/n)" << endl;
yn = getch();
if ( yn == 'y' || yn == 'n' ) { done = true; }
if ( yn == 'y' ) { return false; }
if ( yn == 'n' ) { return true; }
if ( ! (yn == 's' || yn == 'n') ) { cout << "\nyou have entered an invald symbol... \n" << endl; }
if(cin.fail()) { cin.clear(); }
}
}
int main () {
IncomeTax new_tax;
List L;
bool done = false;
while (!done) {
IncomeTax temp = newIncomeTax();
IncomeTax * ptr = &temp;
L.add(ptr);
done = again();
};
return 0;
};
I know that there are many better ways to do the 'if' statements -> i just decided that it would be efficient to just use the if statments -> the professor has stated that there is no need to go beyond this.
Since this is homework I would love to get some feed back on ways that I can use better programing techniques. thanks!
I'm using VS express 2008 C++
Since this is homework I would love to get some feed back on ways that I can use better programing techniques. thanks!
Create separate headers/implementation files for your classes. Don't put all of them in a single header. And put your main in a separate implementation file (call it main.cpp, if you will).
Cut out all the functions that you are not using, and try to create the minimal example that reproduces your error -- that'll help you figure out your issues easily and without needing to come back to SO every now and then. Add one function at a time and see if it compiles, then move on to the next, rinse and repeat.
Another good idea when adding functions is to use stubs -- empty functions just to check if you don't hit any of these unresolved symbol errors (when you're starting out).
You will also need to learn about the syntax -- you don't need a semi-colon after the ending brace of while. You will also learn that members are initialized in the order in which they are declared (so your int member should ideally follow your IncomeTax members). You will need to know what initializer-lists are. And you will need to know about forward declaring.
In short, you will need a book and lots of practice. Here's your code refactored a bit using some of the things I explained above:
class IncomeTax {};
class List
{
private:
IncomeTax * First;
IncomeTax * Last;
int num_in_list;
public:
List () :
First(NULL),
Last(NULL),
num_in_list (0)
{}
~List()
{
// free First and Last ?
}
void add (IncomeTax*) {}
};
int main () {
IncomeTax new_tax;
List L;
bool done = false;
while (!done) {
IncomeTax temp;
L.add(&temp);
done = true;
}
return 0;
}
There's something else you're not telling us here since this should link flawlessly (it did here). I just moved the List class declaration before main() to avoid the class is declared when compiling main but otherwise everything compiles fine.
// Something declared in this order (in the same file or through .h files) should compile & link correctly
class IncomeTax { ... };
class List { ... };
int main() { ... };
It looks like you may have forgotten to add the IncomeTax object file (IncomeTax.o, IncomeTax.obj, etc) into your link command line, and the linker is telling you that it can't find the method definition.
You can test this by temporarily creating a single "whole_project.cpp" file that contains all the code copy-pasted sequentially. If it compiles and links correctly that way, then you just need to edit your makefile/IDE project file/manual command line to specify that it also needs to include the object file.
It only shows the one error because you're only actually calling the add function and none of the other non-inline functions within the list class.
Finally, double check the logic you're using to add items to the list. I believe the temporary you're adding will cause problems since the object goes away as soon as the while loop enters its next iteration.