static members and variables

Discussion in 'C++' started by Gary Wessle, Aug 14, 2006.

  1. Gary Wessle

    Gary Wessle Guest

    Hi

    I am calling a class method on many objects of that class
    alternately. the class needs to make available "remember" values of
    variables of said method for each object separetly when the object
    calls the method again.

    I can't make those variables static inside the method because it will
    hold its value for all objects without discrimination.

    I can't make those variables object attributes because will be erased
    when the object goes out of scope at the closing bracket of the
    alternating mechanize "for loop".

    class mytype
    {
    static int unique;
    public:
    mytype():unique = 0 {}
    void dothis(){
    unique++; <<-- error line

    ....
    };

    undefined reference to `mytype::unique'

    how is this fixed?

    thanks
     
    Gary Wessle, Aug 14, 2006
    #1
    1. Advertising

  2. Gary Wessle

    Rolf Magnus Guest

    Gary Wessle wrote:

    > Hi
    >
    > I am calling a class method on many objects of that class
    > alternately. the class needs to make available "remember" values of
    > variables of said method for each object separetly when the object
    > calls the method again.
    >
    > I can't make those variables static inside the method because it will
    > hold its value for all objects without discrimination.
    >
    > I can't make those variables object attributes because will be erased
    > when the object goes out of scope at the closing bracket of the
    > alternating mechanize "for loop".
    >
    > class mytype
    > {
    > static int unique;
    > public:
    > mytype():unique = 0 {}
    > void dothis(){
    > unique++; <<-- error line
    >
    > ...
    > };
    >
    > undefined reference to `mytype::unique'
    >
    > how is this fixed?


    By defining 'unique'. As it stands above, the variable is only declared, but
    there is no actual storage reserved for it. Add:

    int mytype::unique;

    somewhere in the implementation file.
     
    Rolf Magnus, Aug 14, 2006
    #2
    1. Advertising

  3. Gary Wessle

    Guest

    Hi,

    > mytype():unique = 0 {}

    This is a static variable u need to define this outside the class
    (preferably in cpp file) as
    int mytype::unique = 0;

    Regards,
    Amir Kamerkar
     
    , Aug 14, 2006
    #3
  4. Gary Wessle

    Kai-Uwe Bux Guest

    Gary Wessle wrote:

    > Hi
    >
    > I am calling a class method on many objects of that class
    > alternately. the class needs to make available "remember" values of
    > variables of said method for each object separetly when the object
    > calls the method again.


    I do not fully understand what you mean by "'remember' values".


    > I can't make those variables static inside the method because it will
    > hold its value for all objects without discrimination.


    Ok, apparently, "remember" values could be different for each object.


    > I can't make those variables object attributes because will be erased
    > when the object goes out of scope at the closing bracket of the
    > alternating mechanize "for loop".


    There appears to be a confusion: when the object goes out of scope, it is
    destroyed. Thus, the object cannot "call the method again" (your words from
    the description of your design requirement). Only a different object can
    call the method now. Therefore, "remember" values (whatever they might be)
    should not be required.


    > class mytype
    > {
    > static int unique;
    > public:
    > mytype():unique = 0 {}
    > void dothis(){
    > unique++; <<-- error line
    >
    > ...
    > };
    >
    > undefined reference to `mytype::unique'
    >
    > how is this fixed?


    To help you, one would need to know what problem you are trying to solve.
    Post a minimal complete program that illustrates the difficulty.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Aug 14, 2006
    #4
  5. Gary Wessle

    Gary Wessle Guest

    Rolf Magnus <> writes:

    > Gary Wessle wrote:
    >
    >> Hi
    >>
    >> I am calling a class method on many objects of that class
    >> alternately. the class needs to make available "remember" values of
    >> variables of said method for each object separetly when the object
    >> calls the method again.
    >>
    >> I can't make those variables static inside the method because it will
    >> hold its value for all objects without discrimination.
    >>
    >> I can't make those variables object attributes because will be erased
    >> when the object goes out of scope at the closing bracket of the
    >> alternating mechanize "for loop".
    >>
    >> class mytype
    >> {
    >> static int unique;
    >> public:
    >> mytype():unique = 0 {}
    >> void dothis(){
    >> unique++; <<-- error line
    >>
    >> ...
    >> };
    >>
    >> undefined reference to `mytype::unique'
    >>
    >> how is this fixed?

    >
    > By defining 'unique'. As it stands above, the variable is only declared, but
    > there is no actual storage reserved for it. Add:
    >
    > int mytype::unique;
    >
    > somewhere in the implementation file.


    sure that will fix the error above but still will not satisfy the
    requirement of what I am trying to do, which is keep values in
    variables between method calls for the same object and not for all
    objects.
     
    Gary Wessle, Aug 14, 2006
    #5
  6. Gary Wessle

    Rolf Magnus Guest

    Gary Wessle wrote:

    > Rolf Magnus <> writes:
    >
    >> Gary Wessle wrote:
    >>
    >>> Hi
    >>>
    >>> I am calling a class method on many objects of that class
    >>> alternately. the class needs to make available "remember" values of
    >>> variables of said method for each object separetly when the object
    >>> calls the method again.
    >>>
    >>> I can't make those variables static inside the method because it will
    >>> hold its value for all objects without discrimination.
    >>>
    >>> I can't make those variables object attributes because will be erased
    >>> when the object goes out of scope at the closing bracket of the
    >>> alternating mechanize "for loop".
    >>>
    >>> class mytype
    >>> {
    >>> static int unique;
    >>> public:
    >>> mytype():unique = 0 {}
    >>> void dothis(){
    >>> unique++; <<-- error line
    >>>
    >>> ...
    >>> };
    >>>
    >>> undefined reference to `mytype::unique'
    >>>
    >>> how is this fixed?

    >>
    >> By defining 'unique'. As it stands above, the variable is only declared,
    >> but there is no actual storage reserved for it. Add:
    >>
    >> int mytype::unique;
    >>
    >> somewhere in the implementation file.

    >
    > sure that will fix the error above but still will not satisfy the
    > requirement of what I am trying to do, which is keep values in
    > variables between method calls for the same object and not for all
    > objects.


    As Kai-Uwe wrote, your requirements don't really make sense. If you want to
    remember a value for each object, just make it a non-static member. If the
    object goes out of scope, you don't need to remember the value anymore,
    because the object is gone, too.
     
    Rolf Magnus, Aug 14, 2006
    #6
  7. Gary Wessle

    Siam Guest

    Gary Wessle wrote:
    > sure that will fix the error above but still will not satisfy the
    > requirement of what I am trying to do, which is keep values in
    > variables between method calls for the same object and not for all
    > objects.


    I can't see why you don't simply use non-static member variables?
    Surely thats what they're used for...to hold data for a specific
    object. Yes, the variable will go out of scope when the object is
    destroyed, but in that case you won't be able to call any methods on
    the object anyway..

    Siam
     
    Siam, Aug 14, 2006
    #7
  8. Gary Wessle

    Gary Wessle Guest

    Kai-Uwe Bux <> writes:

    > Gary Wessle wrote:
    >
    >> Hi
    >>
    >> I am calling a class method on many objects of that class
    >> alternately. the class needs to make available "remember" values of
    >> variables of said method for each object separetly when the object
    >> calls the method again.

    >
    > I do not fully understand what you mean by "'remember' values".
    >
    >
    >> I can't make those variables static inside the method because it will
    >> hold its value for all objects without discrimination.

    >
    > Ok, apparently, "remember" values could be different for each object.
    >
    >
    >> I can't make those variables object attributes because will be erased
    >> when the object goes out of scope at the closing bracket of the
    >> alternating mechanize "for loop".

    >
    > There appears to be a confusion: when the object goes out of scope, it is
    > destroyed. Thus, the object cannot "call the method again" (your words from
    > the description of your design requirement). Only a different object can
    > call the method now. Therefore, "remember" values (whatever they might be)
    > should not be required.
    >
    >
    >> class mytype
    >> {
    >> static int unique;
    >> public:
    >> mytype():unique = 0 {}
    >> void dothis(){
    >> unique++; <<-- error line
    >>
    >> ...
    >> };
    >>
    >> undefined reference to `mytype::unique'
    >>
    >> how is this fixed?

    >
    > To help you, one would need to know what problem you are trying to solve.
    > Post a minimal complete program that illustrates the difficulty.
    >
    >
    > Best
    >
    > Kai-Uwe Bux



    #include <string>
    #include <vector>

    using namespace std;



    class acc_holder
    {
    string name;
    double max_weekly_withdraw;
    double daily_withdraw;

    public:
    acc_holder(string nam, double d_withdraw)
    : name(nam),
    daily_withdraw(d_withdraw)
    {
    update_weekly_figurs(double d_withdraw);
    }


    void update_weekly_figurs(double i)
    {
    max_weekly_withdraw += i;
    }
    };



    int main(){


    acc_holder jack("jack", 20);
    acc_holder mary("mary", 24);
    vector<acc_holder> fund_participanets;
    fund_participanets.push_back(jack);
    fund_participanets.push_back(mary);

    // no acc_holder is permited to do 2 or more consecutive transactions
    // there for they must alternate, each is permited 10 transactions.

    for( unsigned i = 0; i<=9; i++){
    for(unsigned j = 0; j<=fund_participanets.size()-1; j++){
    fund_participanets[j].update_weekly_figurs(fund_participanets[j].daily_withdraw);
    }
    }
    }
     
    Gary Wessle, Aug 14, 2006
    #8
  9. Gary Wessle

    Kai-Uwe Bux Guest

    Gary Wessle wrote:

    > Kai-Uwe Bux <> writes:
    >
    >> Gary Wessle wrote:
    >>
    >>> Hi
    >>>
    >>> I am calling a class method on many objects of that class
    >>> alternately. the class needs to make available "remember" values of
    >>> variables of said method for each object separetly when the object
    >>> calls the method again.

    >>
    >> I do not fully understand what you mean by "'remember' values".
    >>
    >>
    >>> I can't make those variables static inside the method because it will
    >>> hold its value for all objects without discrimination.

    >>
    >> Ok, apparently, "remember" values could be different for each object.
    >>
    >>
    >>> I can't make those variables object attributes because will be erased
    >>> when the object goes out of scope at the closing bracket of the
    >>> alternating mechanize "for loop".

    >>
    >> There appears to be a confusion: when the object goes out of scope, it is
    >> destroyed. Thus, the object cannot "call the method again" (your words
    >> from the description of your design requirement). Only a different object
    >> can call the method now. Therefore, "remember" values (whatever they
    >> might be) should not be required.
    >>
    >>
    >>> class mytype
    >>> {
    >>> static int unique;
    >>> public:
    >>> mytype():unique = 0 {}
    >>> void dothis(){
    >>> unique++; <<-- error line
    >>>
    >>> ...
    >>> };
    >>>
    >>> undefined reference to `mytype::unique'
    >>>
    >>> how is this fixed?

    >>
    >> To help you, one would need to know what problem you are trying to solve.
    >> Post a minimal complete program that illustrates the difficulty.
    >>
    >>
    >> Best
    >>
    >> Kai-Uwe Bux

    >
    >
    > #include <string>
    > #include <vector>
    >
    > using namespace std;
    >
    >
    >
    > class acc_holder
    > {
    > string name;
    > double max_weekly_withdraw;
    > double daily_withdraw;
    >
    > public:
    > acc_holder(string nam, double d_withdraw)
    > : name(nam),
    > daily_withdraw(d_withdraw)
    > {
    > update_weekly_figurs(double d_withdraw);
    > }
    >
    >
    > void update_weekly_figurs(double i)
    > {
    > max_weekly_withdraw += i;
    > }
    > };
    >
    >
    >
    > int main(){
    >
    >
    > acc_holder jack("jack", 20);
    > acc_holder mary("mary", 24);
    > vector<acc_holder> fund_participanets;
    > fund_participanets.push_back(jack);
    > fund_participanets.push_back(mary);
    >
    > // no acc_holder is permited to do 2 or more consecutive transactions
    > // there for they must alternate, each is permited 10 transactions.
    >
    > for( unsigned i = 0; i<=9; i++){
    > for(unsigned j = 0; j<=fund_participanets.size()-1; j++){
    >

    fund_participanets[j].update_weekly_figurs(fund_participanets[j].daily_withdraw);
    > }
    > }
    > }


    a) This contains a few errors that prevent it from compiling. Not a big deal
    in this case, but a nuisance.

    b) The code does not illustrate any problem with variables going out of
    scope: your acc_holders jack and mary have been copied into a vector
    (fund_participants) and live there happily through all iterations of the
    nested for loops. You can just use a non-static member variable to keep
    track of anything that the acc_holders need to remember about their last
    transaction.

    c) Should you be pondering how the class acc_holder can ensure the
    requirement that a member function cannot be called twice by the same
    object without another object calling it before, you may consider:

    #include <iostream>
    #include <cassert>

    struct dummy {

    static
    dummy* & last_object ( void ) {
    static dummy* ptr = 0;
    return ( ptr );
    }

    void member_func ( void ) {
    assert( this != last_object() );
    last_object() = this;
    std::cout << "member_func called\n";
    }

    };

    int main ( void ) {
    dummy a;
    dummy b;
    a.member_func();
    b.member_func();
    a.member_func();
    a.member_func(); // this one fails.
    }

    Probably you want to throw an exception instead of using assert().

    d) It is not entirely clear why you are using value semantics for
    acc_holders. I would expect that there is one and only one jack and that
    persons cannot be copied. Thus, I would expect to see a
    shared_ptr<acc_holder> in those places where you have acc_holder. But that
    is an entirely different design issue alltogether.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Aug 14, 2006
    #9
  10. Gary Wessle

    Jim Langston Guest

    "Gary Wessle" <> wrote in message
    news:...
    > Kai-Uwe Bux <> writes:
    >
    >> Gary Wessle wrote:
    >>
    >>> Hi
    >>>
    >>> I am calling a class method on many objects of that class
    >>> alternately. the class needs to make available "remember" values of
    >>> variables of said method for each object separetly when the object
    >>> calls the method again.

    >>
    >> I do not fully understand what you mean by "'remember' values".
    >>
    >>
    >>> I can't make those variables static inside the method because it will
    >>> hold its value for all objects without discrimination.

    >>
    >> Ok, apparently, "remember" values could be different for each object.
    >>
    >>
    >>> I can't make those variables object attributes because will be erased
    >>> when the object goes out of scope at the closing bracket of the
    >>> alternating mechanize "for loop".

    >>
    >> There appears to be a confusion: when the object goes out of scope, it is
    >> destroyed. Thus, the object cannot "call the method again" (your words
    >> from
    >> the description of your design requirement). Only a different object can
    >> call the method now. Therefore, "remember" values (whatever they might
    >> be)
    >> should not be required.
    >>
    >>
    >>> class mytype
    >>> {
    >>> static int unique;
    >>> public:
    >>> mytype():unique = 0 {}
    >>> void dothis(){
    >>> unique++; <<-- error line
    >>>
    >>> ...
    >>> };
    >>>
    >>> undefined reference to `mytype::unique'
    >>>
    >>> how is this fixed?

    >>
    >> To help you, one would need to know what problem you are trying to solve.
    >> Post a minimal complete program that illustrates the difficulty.
    >>
    >>
    >> Best
    >>
    >> Kai-Uwe Bux

    >
    >
    > #include <string>
    > #include <vector>
    >
    > using namespace std;
    >
    >
    >
    > class acc_holder
    > {
    > string name;
    > double max_weekly_withdraw;
    > double daily_withdraw;
    >
    > public:
    > acc_holder(string nam, double d_withdraw)
    > : name(nam),
    > daily_withdraw(d_withdraw)
    > {
    > update_weekly_figurs(double d_withdraw);
    > }
    >
    >
    > void update_weekly_figurs(double i)
    > {
    > max_weekly_withdraw += i;
    > }
    > };
    >
    >
    >
    > int main(){
    >
    >
    > acc_holder jack("jack", 20);
    > acc_holder mary("mary", 24);
    > vector<acc_holder> fund_participanets;
    > fund_participanets.push_back(jack);
    > fund_participanets.push_back(mary);
    >
    > // no acc_holder is permited to do 2 or more consecutive transactions
    > // there for they must alternate, each is permited 10 transactions.
    >
    > for( unsigned i = 0; i<=9; i++){
    > for(unsigned j = 0; j<=fund_participanets.size()-1; j++){
    > fund_participanets[j].update_weekly_figurs(fund_participanets[j].daily_withdraw);
    > }
    > }
    > }
    >


    Just store in your object the last transaction they made.
    Store in a static the last object that made a transaction. I.E. std::string
    name.
    If the current object making the transaction isn't the same as the last one
    (compare the static stored name with the object's name) then you can look at
    the object's last transaction.
     
    Jim Langston, Aug 15, 2006
    #10
    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. Ben
    Replies:
    3
    Views:
    429
  2. SaravanaKumar
    Replies:
    6
    Views:
    9,455
    Tony Morris
    Oct 19, 2004
  3. JFCM
    Replies:
    4
    Views:
    5,756
  4. Hicham Mouline
    Replies:
    5
    Views:
    2,405
    James Kanze
    Dec 19, 2008
  5. Victor Bazarov
    Replies:
    11
    Views:
    759
    James Kanze
    Dec 9, 2009
Loading...

Share This Page