Need Help with a Pointer

Pages: 12
See my posts below to see my "progress" AKA current bug... I'm currently having trouble utilizing the checkOutMember function.
Product.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef PRODUCT_HPP
#define PRODUCT_HPP

#include <string>

class Product
{
private:
    std::string idCode;
    std::string title;
    std::string description;
    double price;
    int quantityAvailable;
public:
    Product(std::string id, std::string t, std::string d, double p, int qa);
    std::string getIdCode();
    std::string getTitle();
    std::string getDescription();
    double getPrice();
    int getQuantityAvailable();
    void decreaseQuantity();
};
#endif 

Customer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef CUSTOMER_HPP
#define CUSTOMER_HPP

#include <vector>
#include "Product.hpp"

class Customer
{
private:
    std::vector<std::string> cart;
    std::string name;
    std::string accountID;
    bool premiumMember;
public:
    Customer(std::string n, std::string a, bool pm);
    std::string getAccountID();
    std::vector<std::string> getCart();
    void addProductToCart(std::string);
    bool isPremiumMember();
    void emptyCart();
};
#endif 

Store.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef STORE_HPP
#define STORE_HPP

#include <string>
#include "Customer.hpp"

class Store
{
private:
    std::vector<Product*> inventory;
    std::vector<Customer*> members;
public:
    void addProduct(Product* p);
    void addMember(Customer* c);
    Product* getProductFromID(std::string);
    Customer* getMemberFromID(std::string);
    void productSearch(std::string str);
    void addProductToMemberCart(std::string pID, std::string mID);
    void checkOutMember(std::string mID);
};
#endif 

Product.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "Product.hpp"
#include<iostream>
#include<string>
using std::cout;
using std::cin;
using std::endl;

//default constructor that sets all fields to 0 or blank
Product::Product(std::string id, std::string t, std::string d, double p, int qa)
{
    idCode = id;
    title = t;
    description = d;
    price = p;
    quantityAvailable = qa;
}

//get product's ID code
std::string Product::getIdCode()
{
    return idCode;
}

//get product's title
std::string Product::getTitle()
{
    return title;
}

//get the description of the product
std::string Product::getDescription()
{
    return description;
}

//get the price of the product
double Product::getPrice()
{
    return price;
}

//get the on-hand quantity of the product
int Product::getQuantityAvailable()
{
    return quantityAvailable;
}

//set the new on-hand quantity after a sale of the product
void Product::decreaseQuantity()
{
    quantityAvailable = quantityAvailable-1;
}
Last edited on
Store.cpp
 
see my most recent post for current code

Customer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<iostream>
#include "Customer.hpp"
using std::cout;
using std::cin;
using std::endl;


//default constructor that sets name, account ID, and premium member to blank/0
Customer::Customer(std::string n, std::string a, bool pm)
{
    name = n;
    accountID = a;
    pm = false;
}

//get the customer's account ID
std::string Customer::getAccountID()
{
    return accountID;
}

std::vector<std::string> Customer::getCart()
{
    return cart;
}


//add the product to the cart
void Customer::addProductToCart(std::string idCode)
{
    cart.push_back(idCode);
}


//return true if the customer is a premium member, otherwise return false
bool Customer::isPremiumMember()
{
    if (premiumMember == true)
    {
        return true;
    }
    else
        return false;
}

//empty the cart of all products added to it
void Customer::emptyCart()
{
    for (std::size_t x = 0; x < cart.size(); x++)
    {
        cart.clear();
    }
}
Last edited on
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <iostream>
#include "Store.hpp"
using std::cout;
using std::cin;
using std::endl;

void printVector(std::vector<std::string> vect);

int main()
{
    
    // create store called shoprite
    Store shoprite;
    
    //Product(std::string id, std::string t, std::string d, double p, int qa);
    Product apple("1000", "Granny Smith", "green apple great for baking", 1.99, 12);
    Product banana("1010", "Chiquita fruit", "great source of K, yellow", 0.49, 14);
    Product watermelon("1111", "Summer Fruit", "Green and juicy", 5.95, 2); // 2 left
    
    //Customer(std::string n, std::string a, bool pm);
    Customer hugh("Hugh Jass", "CMN32", false);
    Customer amanda("Amanda Huggankis", "CMN33", false);
    Customer ben("Ben Dover", "CMN34", true);
    
    shoprite.addMember(&hugh);
    shoprite.addMember(&amanda);
    shoprite.addMember(&ben);
    
    shoprite.addProduct(&apple);
    shoprite.addProduct(&banana);
    shoprite.addProduct(&watermelon);
    
    Customer* pMemb = shoprite.getMemberFromID("CMN32");
    Product* pProd = shoprite.getProductFromID("1000");
    
    pMemb = shoprite.getMemberFromID("CMN32");
    pProd = shoprite.getProductFromID("1000");
    
    // print Member pointer
    if (pMemb != nullptr)
        cout << "Member pointer is " << pMemb << endl;
    else
        cout << "Member pointer is NULL " << pMemb << endl;
    
    // Print Product pointer
    if (pProd != nullptr)
        cout << "Product pointer is " << pProd << endl;
    else
        cout << "Product pointer is NULL " << pProd << endl;
    
    
    
    // Product Search
    shoprite.productSearch("asdfasdf");
    shoprite.productSearch("green");
    shoprite.productSearch("Green");
    shoprite.productSearch("fruit");
    shoprite.productSearch("Fruit");
    
    
    
    
    // Add Products to member carts
    shoprite.addProductToMemberCart("fdsve", "CMN32"); // add invalid product to hugh's cart
    
    shoprite.addProductToMemberCart("1000", "fdaxfe"); // add apple to invalid's cart
    
    
    shoprite.addProductToMemberCart("1000", "CMN32"); // add apple to hugh's cart
    
    printVector(hugh.getCart());
    
    shoprite.addProductToMemberCart("1010", "CMN32"); // add banana to hugh's cart
    
    printVector(hugh.getCart());
    
    shoprite.addProductToMemberCart("1111", "CMN32"); // add watermelon to hugh's cart
    shoprite.addProductToMemberCart("1111", "CMN32"); // add watermelon to hugh's cart
    shoprite.addProductToMemberCart("1111", "CMN32"); // add watermelon to hugh's cart
    
    printVector(hugh.getCart());
    
    
    
    shoprite.addProductToMemberCart("1111", "CMN33"); // add watermelon to amanda's cart (should fault because quantity available is 0)
    
    printVector(amanda.getCart());
    
    
    // Checkout hugh
    shoprite.checkOutMember("CMN32");
    
    
    
    // Checkout amanda
    shoprite.checkOutMember("CMN33");
    
    // Checkout ben (no items yet)
    shoprite.checkOutMember("CMN34");
    
    
    // Checkout invalid ID
    shoprite.checkOutMember("fdas");
    
    
    
    cout << "amanda before ben: " << banana.getQuantityAvailable() << endl << endl;
    
    
    //ben shopping
    shoprite.addProductToMemberCart("1010", "CMN34"); // add banana to ben's cart
    shoprite.addProductToMemberCart("1010", "CMN34"); // add banana to bens's cart
    shoprite.addProductToMemberCart("1010", "CMN34"); // add banana to ben's cart
    shoprite.addProductToMemberCart("1010", "CMN34"); // add banana to ben's cart
    shoprite.addProductToMemberCart("1010", "CMN34"); // add banana to ben's cart
    
    
    cout << "amanda after ben shops (before checking out): " << banana.getQuantityAvailable() << endl << endl;
    
    // Checkout ben (premium member!)
    shoprite.checkOutMember("CMN34");
    
    cout << "amanda after ben shops (and checks out): " << banana.getQuantityAvailable() << endl << endl;
    
    return 0;
}



void printVector(std::vector<std::string> vect)
{
    
    cout << "Vector has " << vect.size() << " elements, which are: ";
    
    for (int i = 0; i < vect.size(); i++)
    {
        cout << vect.at(i) << " ";
    }
    
    cout << endl;
}


To be clear I did not write the header files, only the implementation files.
Last edited on
If you know where there problem is why don't you set a breakpoint and step through this function step by step. When you see the values of your variables the problem is most of the times obvious.
Since you you have all the files to compile and run the program you are in the best position to find the problem.
What IDE do you use.?

BTW your function could be much easier.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Product* Store::getProductFromID(std::string idCode)
{
    Product* productPointer = NULL;
    
    cout << "The product IDs are: \n";
    for(int x=0; x < inventory.size(); x++)
    {
        productPointer = inventory[x];
        //cout << productPointer->getIdCode() << "\n";
        if(productPointer != NULL && productPointer->getIdCode() == idCode) // found it
        {
           return productPointer;
        }
    }
    return NULL;
}
Where do you add Product(s) to Store::inventory?
I'd expect to find some "shoprite.addProduct()" in main()...

Also: where do you declare "target"?

Actually the first problem is in store.cpp customerPointer = members[locationInVector];
members is empty, since you did't add your customers to the store.
In Main.cpp you need to rename your store to target otherwise it won't compile.
Also in the customer and product constructor you need to initialize your member variables.
Last edited on
Hi,

What is target?

It looks as though you are calling functions like getProductFromID before you add products to the inventory.

Some other things:

Pass std::string by reference.

Make parameters const where ever possible in the cpp files.

Avoid using NULL. Use nullptr instead, it was invented for this exact purpose.

I would prefer true or false instead of 1 or 0.

The size function returns a type std::size_t , make for loops like this:

for(std::size_t x = 0; x < inventory.size(); x++) {

The compiler should have warned about that.

If you are going to iterate an entire container, consider using a range based for loop:

1
2
3
for (const auto& item : inventory) {
 // do something with item
}
Thank you everyone, I'll work on this throughout the day.

The use of target in main has been corrected, I've been writing multiple variations and copied/pasted from two different sources. Target should say shoprite, this has been fixed.

Thomas: I am using Xcode, this is the first program I've written in it so I'm not entirely sure what a breakpoint is/how to use it. Prior to this program I wrote everything on Vim. I'll read into that more once I get this thing up and running...
Thanks! I am now having the problem of adding products and members to their respective vectors. I have updated my code above to reflect my progress as of now.

I'm also still having a hard time implementing my isPremiumMember function inside of the checkOutMember function. When I try to implement I get the error that isPremiumMember is not a member of Product, and now (as it is posted above) I get the error "member reference base type Customer...etc.. is not a structure." Don't I have to declare a customer object to access the isPremiumMember function since it is in the Customer class?
The following is the output from my main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
The product IDs are: 
Member pointer is NULL 0x0
Product pointer is NULL 0x0
The product IDs are: 
Member pointer is NULL 0x0
Product pointer is NULL 0x0
Sorry, product not listed.
Sorry, product not listed.
Sorry, product not listed.
Sorry, product not listed.
Sorry, product not listed.
Product # fdsve not foundProduct # 1000 not foundProduct # 1000 not foundVector has 0 elements, which are: 
Product # 1010 not foundVector has 0 elements, which are: 
Product # 1111 not foundProduct # 1111 not foundProduct # 1111 not foundVector has 0 elements, which are: 
Product # 1111 not foundVector has 0 elements, which are: 
 Member # CMN32 not found.
 Member # CMN33 not found.
 Member # CMN34 not found.
 Member # fdas not found.
amanda before ben: 1606681544

Product # 1010 not foundProduct # 1010 not foundProduct # 1010 not foundProduct # 1010 not foundProduct # 1010 not foundamanda after ben shops (before checking out): 1606681544

 Member # CMN34 not found.
amanda after ben shops (and checks out): 1606681544

Program ended with exit code: 0

I assume the garbage values coming out of getQuantityAvailable are due to the objects not entering the vector, making the value meaningless. If I'm off base let me know.

Again I appreciate everyone's help and patience, I'm very new to programming and am learning a lot as I go!
Last edited on
Have a closer look at these constructors:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//default constructor that sets all fields to 0 or blank
Product::Product(std::string id, std::string t, std::string d, double p, int qa)
{
  id = idCode;
  t = title;
  d = description;
  p = price;
  qa = quantityAvailable;
}

//default constructor that sets name, account ID, and premium member to blank/0
Customer::Customer(std::string n, std::string a, bool pm)
{
  n = name;
  a = accountID;
  pm = false;
}
I see my error, I have corrected and flipped the assignments for both constructors. I am able to now see my member vector, however I'm still having trouble adding products to their vector...
1
2
3
4
5
6
7
8
Product::Product(std::string id, std::string t, std::string d, double p, int qa)
{
  idCode = id;
  title = t;
  description = d;
  price = p;
  quantityAvailable = qa;
}


My current output:
1
2
3
4
5
6
7
8
9
10
11
12
1000
The product IDs are: 
The product IDs are: 
Member pointer is 0x7fff5fbfe770
Product pointer is 0x7fff5fbfe970
Sorry, product not listed.
Sorry, product not listed.
Sorry, product not listed.
Sorry, product not listed.
Sorry, product not listed.
Product # fdsve not found Member # fdaxfe not found.
(lldb)
Last edited on
You need to add the products and customers after you created your store at line 23 Store shoprite;
I apologize but isn't that what is happening in lines 41-47?
I was referring to line 25-38. They won't work because you haven't added anything.
Hmm... I rearranged the lines so that what was previously lines 25-38 are now 41-57 and added the products/customers prior to those lines and the output remains the same...
I have continued to wrestle with this and it appears that the objects ARE being passed into the vectors but there is an issue in my addProductToMemberCart function... what the issue is I'm not sure yet...
Hi,

With your constructors:

Consider using a member initialization list. http://en.cppreference.com/w/cpp/language/initializer_list

With your parameter names, I find them too short. I like to name them the same as the member variable but with "Arg" appended. Also they should be marked const and be passed by reference if they are a std::string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Product::Product (const std::string& idCodeArg, 
               const std::string&  titleArg, 
               const std::string&  descriptionArg, 
               const double priceArg, 
               std::size_t quantityAvailableArg // should be 0 or positive
               )
               : // colon introduces member initializer list
               idCode(idCodeArg),
               title(titleArg),
               description(descriptionArg),
               price(priceArg),
               quantityAvailable(quantityAvailableArg)
{
// do error checking here, throw exception if a problem
}


With the const and pass by reference, you need to do something similar to all your other functions.

If one has another constructor (which you have) , then the default constructor can be explicitly defaulted:

Product::Product() = default;

Some of the variable names in the header files are unfortunate (You mentioned you didn't write them). For example pID is ProductID, but in old school terminology a lower case p at the start of a variable means pointer . Will they get upset if you rename them?

Good variable and functions should make the code tell a story of what is happening, without needing extra comments to explain what is going on. Use comments to explain why something is happening, class invariants, expected ranges of values and such like. Here is a comical example of what I mean about names: http://www.cplusplus.com/forum/lounge/176684/#msg872881

An example of a class invariant is that a price should always be positive. So this needs to be checked, because we can't enforce it by choosing an unsigned type (unless one creates Currency classes for it). https://en.wikipedia.org/wiki/Class_invariant


Also, I like to always provide names for parameter variables, not just the type. Make them the same in the declarations and definitions.

There seems to be too much going on in your functions. In Store::addProductToMemberCart the comments describe really well what could be in a function. You could make these functions private:

Maybe some of that output code is poor man's debugging? It is really worthwhile to learn to use the debugger built into your IDE. It will save you days of staring at code.

Another way to find problems is to set your warnings levels high. I am not sure, does Xcode use g++ as it's compiler? If so compile with at least this:

g++ -std=c++14 -Wall -Wextra -pedantic-errors *.cpp -o ExecutableFilename

There are other options not enables by these seemingly comprehensive options: http://www.cplusplus.com/forum/general/183731/#msg899203

You might have to figure out where to set these options in your IDE.


Here is some really good reading:

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#main
https://isocpp.org/faq
https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

Good Luck !!
Invaluable advice, I really appreciate it. I've updated my code above to what I have as of right now. You asked if I am allowed to rename any variables, the answer is no. I asked if it is possible to add some helper functions to the listed code, the answer is no. My understanding is certainly limited, but I hoped to pull some things out of the longer functions like checkOutMember and addProductToMemberCart and make them more readable. Oh well.

The poor man's debugging output code in main is exactly what it is. I've recently "graduated" to an IDE and have so much to learn.

The good news: I am able to implement the addProductToMemberCart function correctly. Objects are being pushed to their respective vectors correctly. Light at the end of the tunnel!

The bad news: I'm having a hard time with my productSearch function. I'm attempting to use string.find() which is not accepting my searched string. For example, when I do this shoprite.productSearch("yellow"); the output is:
1
2
3
4
Apple
ID Code: 1000
Price: $1.99
Granny Smith, green apple great for baking

After I fix this function I can move on to the checkOut function and address the issue of the inventory quantity not changing.

Thanks again for any/all help/suggestions, I'd be drowning right now if it wasn't for everyone's help.
Last edited on
Pages: 12