problem with my code

G

Gary Wessle

Hi

the code below I wrote to mirror the problem I am having in my program,
please note the code below, I am expecting different Consumers in the
same Group to have the same Account information. but I am getting no
information on their joint account as it stands when I fire the method
c->consume() in class Grou_task below,

thanks for you help.


****************************************************************
class Consumer
{
Account* acc;
public:
Consumer(Account* acc){}
void consume();
};
****************************************************************
class Group
{
Account acc;
public:
vector<Consumer> cons_vec;
Group(vector<string> consumer_names)
{
group_them(consumer_names);
}
void group_them(vector<string> cn){
for(vector<string>::const_iterator i=cn.begin();
i!=cn.end(); i++){
Consumer con(&acc);
cons_vec.push_back(con);
}
}
};
****************************************************************
class Grou_task
{
vector<Group> group_vec;
void names2groups();
void operate();
public:
Grou_task()
{
names2groups();
}

void names2groups(){
/* Instantiate a group for each combination of consumers
and populate group_vec.*/
for( ... ) {
vector<string> combi;
for( int i=0; i<10 ;i++) // group of 10 consumers
combi.push_back( some_name_from_vector[k] );

Group group10( combi );
group_vec.push_back( group10 );
}
}

void operate(){
for( vector<Group>::iterator g = group_vec.begin();
g != group_vec.end(); i++ ){
for( vector<Consumer>::iterator c = (g->cons_vec).begin();
c != (g->cons_vec).end(); c++ ){

c->consume();
}
}
}
};
 
S

Salt_Peter

Gary said:
Hi

the code below I wrote to mirror the problem I am having in my program,
please note the code below, I am expecting different Consumers in the
same Group to have the same Account information. but I am getting no
information on their joint account as it stands when I fire the method
c->consume() in class Grou_task below,

thanks for you help.

OK, it goes like this: if you have a member, any member, always
initialize it - if you break that fundamental rule: you suffer the
unfortunate consequences.. Even if its a pointer - initialize it to
nullptr - although you really shouldn't be using pointers at this
point.
****************************************************************
class Consumer
{
Account* acc;
public:
Consumer(Account* acc){}

// acc should be labelled appropriately - its a pointer
// ie: p_acc
Consumer() : acc(0) { }
Consumer(Account* p) : acc(p) { }
void consume();
};
****************************************************************
class Group
{
Account acc;
public:
vector<Consumer> cons_vec;
Group(vector<string> consumer_names)
{
group_them(consumer_names);
}

// set acc below appropriately - or add it as a reference parameter.
Group(std::vector< std::string >& r_consumers) : acc()
{
group_them(consumers);
}
void group_them(vector<string> cn){

make cn a reference also
for(vector<string>::const_iterator i=cn.begin();
i!=cn.end(); i++){
Consumer con(&acc);
cons_vec.push_back(con);
}
}
};
****************************************************************
class Grou_task
{
vector<Group> group_vec;
void names2groups();
void operate();
public:
Grou_task()
{
names2groups();
}

void names2groups(){
/* Instantiate a group for each combination of consumers
and populate group_vec.*/
for( ... ) {
vector<string> combi;
for( int i=0; i<10 ;i++) // group of 10 consumers
combi.push_back( some_name_from_vector[k] );

Group group10( combi );
group_vec.push_back( group10 );
}
}

void operate(){
for( vector<Group>::iterator g = group_vec.begin();
g != group_vec.end(); i++ ){
for( vector<Consumer>::iterator c = (g->cons_vec).begin();
c != (g->cons_vec).end(); c++ ){

c->consume();
}
}
}
};
 
G

Gary Wessle

I followed your suggestions, the code below is expected to putout
15000
14999
15000
14999

but it is only putting out
15000
garbage
garbage
garbage


#include <string>
#include <iostream>
#include <vector>
using namespace std;

class Account {
public:
double balance;
Account() : balance( 15000 ) { }
};
//****************************************************************
class Consumer
{
Account* p_acc;
public:
Consumer(Account* p) :
p_acc( p )
{ }

void consume(){
cout << p_acc->balance-- << endl;
}
};
//****************************************************************
class Group
{
Account acc;
public:
vector<Consumer> consumers;
Group(vector<string> cNames) : acc()
{
group_them( cNames );
}
void group_them(vector<string>& r_cNames){
for(vector<string>::const_iterator i = r_cNames.begin();
i != r_cNames.end(); i++){
Consumer consumer( &acc );
consumers.push_back( consumer );
}
}
};

//****************************************************************
class Grou_task
{
vector<Group> groups;

void operate(){
for( vector<Group>::iterator i_group = groups.begin();
i_group != groups.end(); i_group++ ){
for( vector<Consumer>::iterator i_consumer = (i_group->consumers).begin();
i_consumer != (i_group->consumers).end(); i_consumer++ ){
i_consumer->consume();
}
}
}

void names2groups(){
vector<string> combi1;
combi1.push_back( string( "jack" ) );
combi1.push_back( string( "jacky" ) );
Group group1( combi1 );
groups.push_back( group1 );
vector<string> combi2;
combi2.push_back( string( "dog" ) );
combi2.push_back( string( "dogy" ) );
Group group2( combi2 );
groups.push_back( group2 );
}

public:
Grou_task()
{
names2groups();
operate();
}

};


int main(){
Grou_task();
}
 
S

Salt_Peter

Gary said:
I followed your suggestions, the code below is expected to putout
15000
14999
15000
14999

but it is only putting out
15000
garbage
garbage
garbage


#include <string>
#include <iostream>
#include <vector>
using namespace std;

class Account {
public:
double balance;
Account() : balance( 15000 ) { }
};
//****************************************************************
class Consumer
{
Account* p_acc;

You have provided consumers with a pointer to an account that is
private.
Look at the Group class. That pointer is inaccessible from here.
public:
Consumer(Account* p) :
p_acc( p )
{ }

void consume(){
cout << p_acc->balance-- << endl;

loose the --
and why don't you store and display the names you are loading
below
you can display them here to prove that at least the appropriate
consumers are being accessed.

class Consumer
{
std::string sname;
Account acc;
public:
Consumer(std::string s, Account& a)
: sname(s), acc( a ) { }

void consume() {
std::cout << "name = " << sname;
std::cout << "\t";
std::cout << acc.balance << std::endl;
}
};
//****************************************************************
class Group
{
Account acc;

private account !!!
public:
vector<Consumer> consumers;
Group(vector<string> cNames) : acc()
{
group_them( cNames );
}
void group_them(vector<string>& r_cNames){
for(vector<string>::const_iterator i = r_cNames.begin();
i != r_cNames.end(); i++){
Consumer consumer( &acc );

Can you see the problem? you are passing a private address to consumers
that can't access it.

Consumer consumer( *i, acc );

Note, thats a copy of an account being passed. Not what you want. see
notes at end.
consumers.push_back( consumer );
}
}
};

//****************************************************************
class Grou_task
{
vector<Group> groups;

void operate(){
for( vector<Group>::iterator i_group = groups.begin();
i_group != groups.end(); i_group++ ){
for( vector<Consumer>::iterator i_consumer = (i_group->consumers).begin();

for( std::vector< Consumer >::iterator i_consumer =
(*i_group).consumers.begin();
// same for what is below.
i_consumer != (i_group->consumers).end(); i_consumer++ ){
i_consumer->consume();
}
}
}

void names2groups(){
vector<string> combi1;
combi1.push_back( string( "jack" ) );
combi1.push_back( string( "jacky" ) );
Group group1( combi1 );
groups.push_back( group1 );
vector<string> combi2;
combi2.push_back( string( "dog" ) );
combi2.push_back( string( "dogy" ) );
Group group2( combi2 );
groups.push_back( group2 );
}

public:
Grou_task()
{
names2groups();
operate();
}

};


int main(){
Grou_task();
}

You should rethink your design.

class Bank { }; has groups and accounts and task_operations()

its not the group that has the account, its the bank.
private groups have access to private accounts.
place consumers in the appropriate group and voila!
 
G

Gary Wessle

Salt_Peter said:
You should rethink your design.

class Bank { }; has groups and accounts and task_operations()

its not the group that has the account, its the bank.
private groups have access to private accounts.
place consumers in the appropriate group and voila!

I think so.

ok, here is a new design, but I will need some help, as it is giving
segmentation fault.

#include <string>
#include <iostream>
#include <vector>
using namespace std;

class Account {
double balance;
public:
double withdraw( double a) {
balance -= a;
return balance;
}
Account() : balance( 15000 ) { }
};

//****************************************************************
class Consumer
{
string name;
Account* p_acc;
public:
Consumer(string s, Account* p_a) : name(s), p_acc( p_a ) { }

void consume(int amount){
cout << name << " is withdrawing " << amount << endl;
cout << "New balance is "
<< (*p_acc).withdraw( amount )// <<<<<<<<<<<<<<<< how can I do this?
<< endl;
}
};

//****************************************************************
class Group
{
Account* p_acc;
public:
vector<Consumer> consumers;
Group(vector<string> cNames, Account* p_a) : p_acc( p_a )
{
group_them( cNames );
}
void group_them(vector<string>& r_cNames){
for(vector<string>::const_iterator i = r_cNames.begin();
i != r_cNames.end(); i++){
Consumer consumer( *i, p_acc );
consumers.push_back( consumer );
}
}
};

//****************************************************************
class Bank
{
vector<Group> groups;

void operate(){
for( vector<Group>::iterator i_group = groups.begin();
i_group != groups.end(); i_group++ ){
for( vector<Consumer>::iterator i_consumer = (*i_group).consumers.begin();
i_consumer != (*i_group).consumers.end(); i_consumer++ ){
i_consumer->consume( 5 );
}
}
}
/* some dummy joint accounts for testing */
void names2groups(){
vector<string> combi1;
combi1.push_back( string( "jack" ) );
combi1.push_back( string( "jacky" ) );
Account acc1;
Group group1( combi1, &acc1 );

vector<string> combi2;
combi2.push_back( string( "dog" ) );
combi2.push_back( string( "dogy" ) );
Account acc2;
Group group2( combi2, &acc2 );

groups.push_back( group1 );
groups.push_back( group2 );
}

public:
Bank()
{
names2groups();
operate();
}

};


int main(){
Bank();
}
 
G

Gary Wessle

Ok,
I was toying with boost and found this solution which gave the expected results:
[fred@localhost toy]$ ./proj
jack is withdrawing 5
New balance is 14995
jacky is withdrawing 5
New balance is 14990
dog is withdrawing 5
New balance is 14995
dogy is withdrawing 5
New balance is 14990

I am hoping I did the "right thing"

****************************************************************
#include <string>
#include <iostream>
#include <vector>
#include "boost/smart_ptr.hpp"
using namespace std;

class Account {
double balance;
public:
double withdraw( double a) {
balance -= a;
return balance;
}
Account() : balance( 15000 ) { }
};

//****************************************************************
class Consumer
{
string name;
boost::shared_ptr<Account> p_acc;
public:
Consumer(string s, boost::shared_ptr<Account> p_a) : name(s), p_acc( p_a ) { }

void withdraw(int amount){
cout << name << " is withdrawing " << amount << endl;
cout << "New balance is "
<< p_acc->withdraw( amount )// <<<<<<<<<<<<<<<< how can I do this?
<< endl;
}
};

//****************************************************************
class Group
{
boost::shared_ptr<Account> p_acc;
public:
vector<Consumer> consumers;
Group(vector<string> cNames) : p_acc( new Account )
{
group_them( cNames );
}
void group_them(vector<string>& r_cNames){
for(vector<string>::const_iterator i = r_cNames.begin();
i != r_cNames.end(); i++){
Consumer consumer( *i, p_acc );
consumers.push_back( consumer );
}
}
};

//****************************************************************
class Bank
{
vector<Group> groups;
void operate(){
for( vector<Group>::iterator i_group = groups.begin();
i_group != groups.end(); i_group++ ){
for( vector<Consumer>::iterator i_consumer = (*i_group).consumers.begin();
i_consumer != (*i_group).consumers.end(); i_consumer++ ){
i_consumer->withdraw( 5 );
}
}
}
/* some dummy joint accounts for testing */
void names2groups(){
vector<string> combi1;
combi1.push_back( string( "jack" ) );
combi1.push_back( string( "jacky" ) );
Group group1( combi1 );

vector<string> combi2;
combi2.push_back( string( "dog" ) );
combi2.push_back( string( "dogy" ) );
Group group2( combi2 );

groups.push_back( group1 );
groups.push_back( group2 );
}

public:
Bank()
{
names2groups();
operate();
}

};


int main(){
Bank();
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top