Modifying the vector of one class in another class?

If I wanted to modify the vector of another class inside my second class, is it possible?

I wish to tell the second class everytime I increase or decrease the food(increaseFood/decreaseFood) instead of having to re-scan every fridge.


If I made another function in my checkFoodSupply class, like "FoodSupplyChanged" which modified the vector of that class, would it be possible to do something like

if(fullFridges<fridgez){
emptyFridges--;
fullFridges++;
// FoodSupplyChanged +2; //The food supply changed function would increase the total food
return fullFridges;}

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
                     #include <iostream>
            #include <string>
            typedef unsigned long T;
            #include <vector>
            class Condo
            {
                public:
    
                Condo(unsigned int fridgenumber);//total number of fridges
    
                double foodSupply() const; // returns total amount of food in all fridges, if a fridge has food it counts as 2 food supply.
                unsigned int buyFood(); //fills one fridge up
    
                unsigned int eatFood();//empties an entire fridge
    
                private:
                unsigned int fridgez;
                unsigned int fullFridges;
                unsigned int emptyFridges;
            };
    
            Condo::Condo(unsigned int fridgenumber)
            :
            fridgez(fridgenumber),
            fullFridges(0),
            emptyFridges(fridgenumber)
    
            {}
    
    
            unsigned int Condo::buyFood(){
                if(fullFridges<fridgez){
               emptyFridges--;
               fullFridges++;
               return fullFridges;}
                else
               return fullFridges;;
            }
    
            double Condo::foodSupply() const{
                return fullFridges*2;
            }
    
            unsigned int Condo::eatFood(){
                 if(emptyFridges< fridgez){
               emptyFridges++;
               fullFridges--;
               return fullFridges;}
               else
                return fullFridges;
            }
    
            struct foodAmount
            {
                //! food amount at time of test.
                double food;
    
    
                T time;
            };
    
    
            class checkFoodSupply
            {
                public:
            // Condo's being checked  
    
                checkFoodSupply(const std::vector<Condo>& Condos);
    
    
                double recordFood(T nT);//record amount of food currently being contained by all the condo's and record it for later 
    
    
                //record of food records 
                std::vector<foodAmount> records() const;
    
    
                private:
                std::vector<Condo> CondoSupply;
                std::vector<foodAmount> recordsP;
    
            };
            checkFoodSupply::checkFoodSupply(const std::vector<Condo>& Condos):
            CondoSupply(Condos)
            {}
          double checkFoodSupply::recordFood(T nT) {
    double total_supply = 0.0;
    for (auto & condo : CondoSupply)    // for each condo in CondoSupply
    {
        total_supply+=condo.foodSupply();
    }
    recordsP.push_back({total_supply,nT});
    
    return total_supply;
}
    
    std::vector<foodAmount> checkFoodSupply::records() const{
return recordsP;}
            int main()
            
        {   unsigned int x=0;
            unsigned int fridgeNum=10;
            Condo myCondo(fridgeNum);
            Condo myCondo1(11);
            Condo myCondo2(12);
            std::vector<Condo> CondoList={myCondo,myCondo1,myCondo2};
            checkFoodSupply CondoTest(CondoList);
            std::vector<foodAmount> records;
            records = CondoTest.records();
T t;
for(t = 0; t < 10; t++){
  CondoTest.recordFood(t);
}


x = records[1].time;
std::cout<<x;
}
First, I have a few notes on style.

typedef unsigned long T;
Don't do this. By convention, T is used to denote a template parameter when defining simple templates, and more generally as a placeholder for an unknown type (e.g. as in the sentence "suppose there's a function foo() that takes a T ...").
This typedef makes your code much harder to read. Use the more conventional typedef unsigned long ulong;.

Also, you're not using a consistent style.
* Indentation should follow code structure.
* Use blank lines, but not at random. Use them to separate distinctly related code sections. More than a single blank line in a row is almost never a good idea, as they spread the code too far apart.
* Use consistent names. Either use CamelCase or underscore_variable_names. IMO it's okay to use different naming styles for different kinds of things. I like to name classes LikeThis (but not likeThis) and functions and variables like_this.
* With the exception of for loop indices, avoid single letter variable names. You should never use 'x' unless it's in a mathematical context, and even then you should be careful to avoid producing code that's difficult to follow.
* This is less important than the other bullet points, but classes should be named like things (e.g. CustomerRecord) and functions should be named like actions (e.g. 'get_customer_id()'), with some exceptions (e.g. 'vincenty_distance()', or 'shortest_path()', but it could be argued that they could be renamed to 'compute_vincenty_distance()' and 'find_shortest_path()'). A class named checkFoodSupply is strange and suggests perhaps poor design.

Here's your code cleaned up. You don't have to follow the particular style I used here, but you should be consistent and clear.
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
#include <iostream>
#include <string>
#include <vector>

typedef unsigned long ulong;

class Condo
{
public:
    Condo(unsigned int fridgenumber);//total number of fridges
    double foodSupply() const; // returns total amount of food in all fridges, if a fridge has food it counts as 2 food supply.
    unsigned int buyFood(); //fills one fridge up
    unsigned int eatFood();//empties an entire fridge

private:
    unsigned int fridgez;
    unsigned int fullFridges;
    unsigned int emptyFridges;
};

Condo::Condo(unsigned int fridgenumber)
    :
    fridgez(fridgenumber),
    fullFridges(0),
    emptyFridges(fridgenumber)
{}


unsigned int Condo::buyFood()
{
    if(fullFridges<fridgez)
    {
        emptyFridges--;
        fullFridges++;
        return fullFridges;
    }
    else
        return fullFridges;;
}

double Condo::foodSupply() const
{
    return fullFridges*2;
}

unsigned int Condo::eatFood()
{
    if(emptyFridges< fridgez)
    {
        emptyFridges++;
        fullFridges--;
        return fullFridges;
    }
    else
        return fullFridges;
}

struct foodAmount
{
    //! food amount at time of test.
    double food;
    ulong time;
};


class checkFoodSupply
{
public:
    // Condo's being checked
    checkFoodSupply(const std::vector<Condo>& Condos);
    double recordFood(ulong nT);//record amount of food currently being contained by all the condo's and record it for later
    //record of food records
    std::vector<foodAmount> records() const;

private:
    std::vector<Condo> CondoSupply;
    std::vector<foodAmount> recordsP;
};

checkFoodSupply::checkFoodSupply(const std::vector<Condo>& Condos):
    CondoSupply(Condos)
{}

double checkFoodSupply::recordFood(ulong nT) {
    double totalSupply = 0.0;
    for (auto & condo : CondoSupply)    // for each condo in CondoSupply
    {
        totalSupply+=condo.foodSupply();
    }
    recordsP.push_back( {totalSupply,nT});

    return totalSupply;
}

std::vector<foodAmount> checkFoodSupply::records() const
{
    return recordsP;
}

int main()
{
    unsigned int myCondo1Time = 0;
    unsigned int fridgeNum = 10;
    Condo myCondo(fridgeNum);
    Condo myCondo1(11);
    Condo myCondo2(12);
    std::vector<Condo> CondoList= {myCondo,myCondo1,myCondo2};
    checkFoodSupply CondoTest(CondoList);
    std::vector<foodAmount> records;
    records = CondoTest.records();
    ulong t;
    
    for(t = 0; t < 10; t++)
    {
        CondoTest.recordFood(t);
    }

    myCondo1Time = records[1].time;
    std::cout<<myCondo1Time;
}
Now, about your actual question.
Yes, it can be done; no, I don't think it's a good idea in this case. Your Condo class would have to know about your checkFoodSupply class in order for it to work. A Condo only needs to know how to update itself; it has no business knowing that a checkFoodSupply class exists and needs to be notified when its food supply changes.

There are ways to do this generically that don't increase coupling (https://en.wikipedia.org/wiki/Coupling_%28computer_programming%29 ) between classes, but they're way overkill for this.
Last edited on
Thanks for the help.

Maybe I'm explaining it badly, basically I want to automatically tell my checkFoodSupply class if there has been a change in any of the Condo's food supply. This would let me automatically update the code without having to input anything... so for example could I add a new method inside checkFoodSupply to do something like:

 
double changeInFoodSupply(double changed);//This method will automatically be called when food is added or removed from any Condo inside the vector. 


I would also no longer need to input the new time, so I could change it to something like this:(I'm confused about how I'd do this though..)
1
2
3
4
5
6
7
typedef unsigned long ulong;

//unlong now();//to get an automatic time value

//And change the methods to be...
recordFood(ulong nT) {//old
recordFood(){// 


And of course .. for both eatFood and buyFood
1
2
3
4
5
6
7
8
9
10
11
12
unsigned int Condo::eatFood()
{
    if(emptyFridges< fridgez)
    {
        emptyFridges++;
        fullFridges--;
        //changeInFoodSupply(2);//This is where I'd update the second class from the first, automatically telling it the total food amount has changed. Not sure how to call this function though... 
        return fullFridges;
    }
    else
        return fullFridges;
}


For the constructor, I'd pass the second class in by reference
1
2
3
4
5
6
7
Condo::Condo(checkFoodSupply& supply, unsigned int fridgenumber)
    :
    fridgez(fridgenumber),
    fullFridges(0),
    emptyFridges(fridgenumber)
   //Need to initialize the second classes pass by reference here..
{}


So basically, if food is eaten or bought, send a new value to the second vectors class and tell it that the value has changed, instead of testing the result over and over to find out of it was changed.
Last edited on
Yes, I understood what you meant. I still think it would be a mistake to do it.
Just for educational purposes, here's what an update mechanism would look somewhat like. This design should be used with generators and consumers that would naturally need to know about each other. I insist that Condo should not know about checkFoodSupply. Your current design is not generic enough to fit this solution.
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
class EventConsumer;

class EventGenerator{
    EventConsumer *consumer;
    int some_state;
public:
    void update_internal_state();
    int get_state() const{
        return this->some_state;
    }
}

class EventConsumer{
    std::vector<EventGenerator> generators;
public:
    void notify_state_update(EventGenerator *generator);
};

void EventGenerator::update_internal_state(){
    this->some_state++;
    this->consumer->notify_state_update(this);
}

void EventConsumer::notify_state_update(EventGenerator *generator){
    //Alter own state in response to event.
}
I'm not really sure how to use pointers yet...

Would I need to use pointers to modify this? I fixed my code so it works, I just changed some functions and it's having trouble compiling...

I guess my #1 question is how do I initialize below in my constructor, it works before I added that and not now.
Condo::Condo(checkFoodSupply& checkF, unsigned int fridgenumber)

MY second question is, how would I create a command inside my unsigned int Condo::eatFood() function, which automatically would send a value to " double foodAmountDifferent(double different); everytime food is eaten?

I think it will work if I get those functions done, and then implement my foodAmountDifferent function to update the vector, or is my logic wrong?



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
#include <iostream>
#include <string>
#include <vector>

typedef unsigned long ulong;
ulong now();
class Condo
{
public:
    Condo(unsigned int fridgenumber);//total number of fridges
    double foodSupply() const; // returns total amount of food in all fridges, if a fridge has food it counts as 2 food supply.
    unsigned int buyFood(); //fills one fridge up
    unsigned int eatFood();//empties an entire fridge

private:
    unsigned int fridgez;
    unsigned int fullFridges;
    unsigned int emptyFridges;
};

Condo::Condo(checkFoodSupply& checkF, unsigned int fridgenumber)
    :
    fridgez(fridgenumber),
    fullFridges(0),
    emptyFridges(fridgenumber)
{}


unsigned int Condo::buyFood()
{
    if(fullFridges<fridgez)
    {   
        emptyFridges--;
        fullFridges++;
        return fullFridges;
    }
    else
        return fullFridges;;
}

double Condo::foodSupply() const
{
    return fullFridges*2;
}

unsigned int Condo::eatFood()
{
    if(emptyFridges< fridgez)
    {
        emptyFridges++;
        fullFridges--;
        return fullFridges;
    }
    else
        return fullFridges;
}

struct foodAmount
{
    //! food amount at time of test.
    double food;
    ulong time;
};


class checkFoodSupply
{
public:
    // Condo's being checked
    checkFoodSupply(const std::vector<Condo>& Condos);
    double recordFood();//record amount of food currently being contained by all the condo's and record it for later
    //record of food records
    double foodAmountDifferent(double different);
    std::vector<foodAmount> records() const;

private:
    std::vector<Condo> CondoSupply;
    std::vector<foodAmount> recordsP;
};

checkFoodSupply::checkFoodSupply(const std::vector<Condo>& Condos):
    CondoSupply(Condos)
{}
double foodAmountDifferent(double different){}
    
double checkFoodSupply::recordFood() {
    double totalSupply = 0.0;
    for (auto & condo : CondoSupply)    // 
    {
        totalSupply+=condo.foodSupply();
    }
    recordsP.push_back( {totalSupply,ulong});

    return totalSupply;
}

std::vector<foodAmount> checkFoodSupply::records() const
{
    return recordsP;
}

int main()
{
    unsigned int fridgeNum = 10;
    Condo myCondo(fridgeNum);
    Condo myCondo1(11);
    Condo myCondo2(12);
    myCondo.buyFood();
    myCondo.buyFood();
    std::vector<Condo> CondoList= {myCondo,myCondo1,myCondo2};
    checkFoodSupply CondoTest(CondoList);
    
  
    
    ulong t=0;
    
    for(t = 0; t < 10; t++)
    {
        CondoTest.recordFood(t);
    }
  std::vector<foodAmount> records;
    records = CondoTest.records();
    std::cout<<records[1].time<<" "<<records[1].food;
}
Last edited on
Topic archived. No new replies allowed.