Creating a vector containing a pointer to class

Pages: 12
I am working on a problem with 2 classes known as product and order. The product class will hold the attributes of items in stock and the order class will hold attributes of orders. They will be held in two seperate arrays known as P[] and O[] respectively.

My problem is that each order HAS A product number, when the product number is entered I need some way of returning the unit price which is an attribute held in the product class and not the order class. I was initially told that I should complete this problem via the use of a derived class, but I have since been told that a vector holding pointer information to the class is the best solution to the problem but I am unsure as to how to go about it and would be very grateful for some tips.

My code is as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class product
{
   char product_name[20];
   int product_code;
   float unit_price;
   public:
   void getproducts();
   void displayproducts();
   
};

class order: public product
{
   int order_no;
   int product_code;
   int quantity;
   public:
   float totalprice(float x, int y);
   void invoice(void);
   void getorder(void);
   void line(void);
};


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
#include <stdio.h>
#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include <vector.h>

void product::getproducts(void)
{
   cout << "Enter Product Name : ";
   cin.getline(product_name,20);
   cout << "Enter Product Code : ";
   cin >> product_code;
   cout << "Enter Unit Price : ";
   cin >> unit_price;
   cin.ignore();

}

void product::displayproducts(void)
{
   cout << "Product Name : " << product_name;
   cout << "\nProduct Code : " << product_code;
   cout << "\nUnit Price : " << unit_price;
}

void order::getorder(void)
{
   cout << "Enter Order No : ";
   cin >> order_no;
   cout << "Enter Product Code : ";
   cin >> product_code;
   cout << "Enter Quantity : ";
   cin >> quantity;
}

float order::totalprice(float a, int b)
{
   return a*b;
}

void order::line(void)
{
 	for(int x=0;x<44;x++)
   	cout << "-";
}

void order::invoice()
{
    char dateStr [9];
    cout << "\n";
    line();
    cout << "\n|" << " ABC Company Invoice       Date: " 
         << _strdate(dateStr) << " |\n";
    line();
    cout << "\n|" << " Order No                  |      " 
         << order_no << "       |" ;
    cout << "\n|" << " Product code              |   " 
         << product_code << "       |" ;
    cout << "\n|" << " Quantity " << quantity 
         << "  @ Unit Price  |         ***  |\n" << (float)unit_price;
    line();
    cout << "\n|" << " Total price               |         ***  |\n";
    line();
}

main()
{
    product P[3];  //object of type product
    order O[3]; // object of type order

    for(int i=0;i<3;i++)
    {
      cout << "\nEnter Product " << (i+1) << " Information";
      cout << "\n---------------------------\n";
      P[i].getproducts();
    }

   cout<<"\n";
   for(int i=0;i<3;i++)
   {
      cout << "\n\nProduct P" << (i+1);
      cout << "\n---------\n";
      P[i].displayproducts();
   }

   cout<<"\n";
   for(int i=0;i<3;i++)
   {
      cout << "\nEnter Order Information " << (i+1);
      cout << "\n------------------------\n";
      O[i].getorder();
   }

   cout<<"\n";
   for(int i=0;i<3;i++)
   {
      cout << "\n\nOrder No: " << (i+1);
      cout << "\n---------\n";
      O[i].invoice();
   }
 	getche();
}
 
vector<product> productList;


If I try to declare a vector of products after the products have bene initialised into the array I am getting several error messages stating:

Undefined symbol vector
Improper use of typedef product
Ambiguos operators need parenthesis
Undefined symbol product list

This is despite the fact that have also included the vector.h file used in the tutorials on vectors
I would think that this would be better suited to:

Product - for a single product
Order - for a single order (which contains a vector<Product>)

Try:
std::vector<product> productList;

Actually, could you post all of your code? It seems like there is either something that you have not shown us, or you're missing some stuff...
Last edited on
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

#include <stdio.h>
#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include <vector.h>
#include "derived.h"

void product::getproducts(void)
{
   cout << "Enter Product Name : ";
   cin.getline(product_name,20);
   cout << "Enter Product Code : ";
   cin >> product_code;
   cout << "Enter Unit Price : ";
   cin >> unit_price;
   cin.ignore();

}

void product::displayproducts(void)
{
   cout << "Product Name : " << product_name;
   cout << "\nProduct Code : " << product_code;
   cout << "\nUnit Price : " << unit_price;
}

void order::getorder(void)
{
   cout << "Enter Order No : ";
   cin >> order_no;
   cout << "Enter Product Code : ";
   cin >> product_code;
   cout << "Enter Quantity : ";
   cin >> quantity;
}

float order::totalprice(float a, int b)
{
   return a*b;
}

void order::line(void)
{
 	for(int x=0;x<44;x++)
   	cout << "-";
}

void order::invoice()
{
    char dateStr [9];
    cout << "\n";
    line();
    cout << "\n|" << " ABC Company Invoice       Date: "
         << _strdate(dateStr) << " |\n";
    line();
    cout << "\n|" << " Order No                  |      " 
         << order_no << "       |" ;
    cout << "\n|" << " Product code              |   " 
         << product_code << "       |" ;
    cout << "\n|" << " Quantity " << quantity 
         << "  @ Unit Price  |         ***  |\n" << (float)unit_price;
    line();
    cout << "\n|" << " Total price               |         ***  |\n";
    line();
}

main()
{
    product P[3];  //object of type product
    order O[3]; // object of type order

    for(int i=0;i<3;i++)
    {
      cout << "\nEnter Product " << (i+1) << " Information";
      cout << "\n---------------------------\n";
      P[i].getproducts();
    }

    vector<product> productList;

   cout<<"\n";
   for(int i=0;i<3;i++)
   {
      cout << "\n\nProduct P" << (i+1);
      cout << "\n---------\n";
      P[i].displayproducts();
   }

   cout<<"\n";
   for(int i=0;i<3;i++)
   {
      cout << "\nEnter Order Information " << (i+1);
      cout << "\n------------------------\n";
      O[i].getorder();
   }

   cout<<"\n";
   for(int i=0;i<3;i++)
   {
      cout << "\n\nOrder No: " << (i+1);
      cout << "\n---------\n";
      O[i].invoice();
   }
 	getche();
}


and also included in the "derived.h" is the code for product and order:

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
#include <stdio.h>
#include <iostream.h>
#include <conio.h>
#include <math.h>


class product
{

   public:
   /*
   product(char pn[30], int pc, float up)
   {
    	pn = product_name;
      pc = product_code;
      up = unit_price;
   }
   */
   product *pProduct;
   char product_name[20];
   int product_code;
   float unit_price;
   void getproducts();
   void displayproducts();

};

class order: public product
{

   public:                        
   order()
   {

   }
   int order_no;
   int product_code;
   int quantity;
   float getUnit(int a);
   float totalprice(float x, int y);
   void invoice();
   void getorder(void);
   void line(void);
};
I have added in the std:: to the beginning of the line and it is now compiling. I have then tried to put the values of the product array into the vector by using the code:

 
std::vector<product> productList(P, P + sizeof(P)/sizeof(P);


which is syntax that I have found in the vector documentation but I am now getting the error message:

Improper use of typedef std::vector<product>
Close. Try:
std::vector<product> productList( P, P + sizeof( P ) / sizeof( product ) );

However, you are making an array and then using it to populate the vector... Either use the array or use the vector; you shouldn't need both!
Last edited on
thanks seymore at least I have the thing initialised now. Can you give me a tip on how I could access the unit price of a product number ordered.
Try this in one of your for loops:
cout << productList[i].unit_price << endl;
This is now returning the correct value for each of the unit prices, I now need to take the product number entered by the user and referece it with the unit price for that item but I am unsure where in the program to do it. I think the code may be along the lines of:

1
2
3
4
5
for(int i = 0; i < 3; i++)
{
   if(product_no == productList[i].product_no)
          return productList[i].unit_price;
}
Will I need to pass the productList to the order::invoice which displays the invoice on screen if I want to be able to do this? I have tried passing the vector to this by the code:

1
2
3
4
5
6
7
8
void order::invoice(vector<product> productList)
{
	for(int i = 0; i < 3; i++)
	{
   if(product_code == productList[i].product_no)
          float unitPrice = productList[i].unit_price;
	}
Just for comparison, I just wrote this to model a little sale mechanism:
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
142
143
144
145
146
147
148
#include <iostream>
#include <map>

using namespace std;

class Product
{
    // product attributes
    unsigned int _number; // this needs to be unique
    string _name;
    double _price;

    // declared but not defined to prevent an uninitialized product
    Product();

public:

    Product( unsigned int number, string name, double price )
      : _number( number ),
        _name( name ),
        _price( price )
    {
    }

    unsigned int getNumber() const { return _number; }

    string getName() const { return _name; }

    double getPrice() const { return _price; }

    // dumps data for debugging/testing
    void dump() const
    {
        cout << _number << endl << _name << endl << _price << endl;
    }

};

class Catalog
{
    // maps are associative containers, here it maps a
    // unique product number to an actual Product object pointer
    typedef unsigned int ProductNumber;
    typedef map<ProductNumber, Product *> Products;

    Products _products;

    Catalog()
    {
        // read catalog from disk or something here
        // to initialize the Product objects
        ProductNumber number( 1 );
        _products[number] = new Product( number, "XYZ", 1.99 ); ++number;
        _products[number] = new Product( number, "ABC", 0.99 ); ++number;
        _products[number] = new Product( number, "CAR", 999.99 ); ++number;
    }

    ~Catalog()
    {
        // destroy the dynamically created Product objects
        for( Products::iterator i = _products.begin(); i != _products.end(); ++i )
        {
            delete (*i).second;
        }
    }

    // this maintains the Catalog singleton
    static Catalog & instance()
    {
        static Catalog catalog;
        return catalog;
    }

public:

    // this method looks up a Product object given the unique number
    static Product & getProduct( unsigned int number )
    {
        return *instance()._products[number];
    }

};

class Order
{
    typedef unsigned int ProductNumber;
    typedef unsigned int Quantity;
    typedef map<ProductNumber, Quantity> Products;

    unsigned int _number;
    string _customer;
    Products _products;

    Order();

public:

    Order( unsigned int number, string customer )
      : _number( number ),
        _customer( customer )
    {
    }

    void add( const Product & product, unsigned int quantity = 1 )
    {
        _products[product.getNumber()] = quantity;
    }

    // compute the total price of the items in the order
    double total() const
    {
        double total( 0 );
        for( Products::const_iterator i = _products.begin(); i != _products.end(); ++i )
        {
            // for each product in the order, total += unit price * quantity
            total += Catalog::getProduct( (*i).first ).getPrice() * (*i).second;
        }
        return total;
    }

    // dumps data for debugging/testing
    void dump() const
    {
        cout << _number << endl << _customer << endl;
        for( Products::const_iterator i = _products.begin(); i != _products.end(); ++i )
        {
            cout << endl;
            Catalog::getProduct( (*i).first ).dump();
        }
    }

};

int main( int argc, char * argv[] )
{
    // consider creating a Store class or something to manage creating sales

    // create a sale
    Order sale( 1, "Customer" );
    sale.add( Catalog::getProduct( 1 ) );
    sale.add( Catalog::getProduct( 2 ), 2 );

    sale.dump();

    cout << endl << "TOTAL: " << sale.total() << endl;

    return 0;
}


This is more of what I would expect. At least 3 classes, not just 2. I don't recommend you copy this code, but do use it for ideas.

The main difference is that in my version, there is only one set of objects that are products and all other storage of products only store a unique product number that can be looked up from the catalog of product objects.
Last edited on
This is way too complicated for me to understand at the moment and I am afraid that you have completely lost me. I do not even understand the first line of main, what does this mean:

1
2
int main( int argc, char * argv[] )
{


On the basic level at which I am coding can you tell me how I can pass the vector to the invoice::order() method
Last edited on
You need to accept a product number from the user and look up its price, right?

...from what you posted, change the parameter to be "const std::vector<product> & productList" and let me know how it goes.
I have changed the code to the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void order::invoice(const std::vector<product> &productList)
{
	for(int i = 0; i < 3; i++)
	{
   if(product_code == productList[i].product_no)
          float unitPrice = productList[i].unit_price;
	}
    char dateStr [9];
    cout << "\n";
    line();
    cout << "\n|" << " ABC Company Invoice       Date: "
         << _strdate(dateStr) << " |\n";
    line();
    cout << "\n|" << " Order No                  |      " 
         << order_no << "       |" ;
    cout << "\n|" << " Product code              |   " 
         << product_code << "       |" ;
    cout << "\n|" << " Quantity " << quantity 
         << "  @ Unit Price  |         ***  |\n" << (float)unitPrice;
    line();
    cout << "\n|" << " Total price               |         ***  |\n";
    line();
}


I have it declared within the public section of the order class by:

 
void invoice(vector<product> *productList);


And I am calling it in main by the line:

 
O[i].invoice(productList);


I am getting several errors in the code including:
) expected - which takes me declaration of the invoice method in order class
order::invoice(const std::vector<product> &) is not a member of order
10 illegal character warnings
invoice is not a member of order
The declaration needs to match the definition:

void invoice(const std::vector<product> &productList);
Thank you very much for your help seymore the unit price is now being displayed thank you very much for your help. Can you explain to me what the const std::vector<product> & productList); actually does as compared to what I had. What is the significance of the const and & ?
I just re-read your initial post, and I'm convinced that you do not want to have order inherit from product. I strongly suggest that you set this program aside and start fresh.

Write on paper what you need to store in each class and what accesses what... I'm pretty sure that you'll find the following relationship: "orders have products". That statement would mean that there should be a container of products as a member of an order. The way you currently have it modeled is: "orders are products" which implies the "is a" (public inheritance) relationship.

Once you have a plan, then write some new clean classes. (You can copy and paste what is still good from before, like the user input and output formatting parts)
why would there need to be a container for products as a member of order? The way I have the vector set now seems to be working fine as the correct values are being returned for each of the product numbers.
What you had would work, also (assuming you made both the declaration and the definition match up).

1
2
void func1( int a ) {}
void func2( int & b ) {}


func1 would copy the int passed to it and use a local copy inside the function.
func2 would use the real variable passed to it inside the function.

The const keyword (in addition to func2) doesn't let you modify the value of the real variable from inside the function.

Since vector's can be large, you wouldn't want to copy all of that data just for a read-only operation, so you pass it "const to reference". Pointers would also work similarly, but references are a little cleaner.
If your output is acceptable then you may keep using what you have. I'm just making suggestions. If this is a homework assignment or something, you might want to ask your instructor if you are on the right track, that's all.
Pages: 12