problem with my code

Discussion in 'C++' started by Gary Wessle, Dec 1, 2006.

  1. Gary Wessle

    Gary Wessle Guest

    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();
    }
    }
    }
    };
     
    Gary Wessle, Dec 1, 2006
    #1
    1. Advertising

  2. Gary Wessle

    Salt_Peter Guest

    Gary Wessle wrote:
    > 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();
    > }
    > }
    > }
    > };
     
    Salt_Peter, Dec 1, 2006
    #2
    1. Advertising

  3. Gary Wessle

    Gary Wessle Guest

    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();
    }
     
    Gary Wessle, Dec 1, 2006
    #3
  4. Gary Wessle

    Salt_Peter Guest

    Gary Wessle wrote:
    > 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!
     
    Salt_Peter, Dec 1, 2006
    #4
  5. Gary Wessle

    Gary Wessle Guest

    "Salt_Peter" <> writes:

    > Gary Wessle wrote:
    > > I followed your suggestions, the code below is expected to putout
    > >
    > > ...


    > > 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!


    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();
    }
     
    Gary Wessle, Dec 1, 2006
    #5
  6. Gary Wessle

    Gary Wessle Guest

    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();
    }
     
    Gary Wessle, Dec 1, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?Q2FybG8gTWFyY2hlc29uaQ==?=

    Fire Code behind code AND Javascript code associated to a Button Click Event

    =?Utf-8?B?Q2FybG8gTWFyY2hlc29uaQ==?=, Feb 10, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    21,364
    =?Utf-8?B?Q2FybG8gTWFyY2hlc29uaQ==?=
    Feb 11, 2004
  2. Alan Silver
    Replies:
    1
    Views:
    1,744
    Alan Silver
    Sep 15, 2005
  3. keithb
    Replies:
    1
    Views:
    957
    Bruce Barker
    Mar 29, 2006
  4. Replies:
    0
    Views:
    477
  5. thedarkman
    Replies:
    5
    Views:
    740
    Denis McMahon
    Sep 14, 2010
Loading...

Share This Page