Can't access static member var from static method. Why?

Discussion in 'C++' started by Markus Dehmann, Jun 30, 2004.

  1. My ("static") California class has a list of cities, and a static
    member function returns true if a certain city is contained:

    California::contains("San Francisco"); // true

    I implemented it like below, but it does not compile. It gives me some
    obscure linker error (see below). What's wrong with my code?

    #include <iostream>
    #include <map>

    class California{
    private:
    static std::map<std::string, int> cities;
    public:
    California(){
    cities.insert(std::make_pair("San Francisco", 1));
    }
    static bool contains(std::string city){
    return cities.find(city) != cities.end();
    }
    };

    int main(){
    if(California::contains("San Francisco")){
    std::cout << "SF is in CA!" << std::endl;
    }
    }

    bash-2.05b$ g++ california.cpp
    /tmp/ccduZZS6.o(.gnu.linkonce.t._ZN10California8containsESs+0x11): In
    function `California::contains(std::basic_string<char,
    std::char_traits<char>, std::allocator<char> >)':
    : undefined reference to `California::cities'
    /tmp/ccduZZS6.o(.gnu.linkonce.t._ZN10California8containsESs+0x2a): In
    function `California::contains(std::basic_string<char,
    std::char_traits<char>, std::allocator<char> >)':
    : undefined reference to `California::cities'
    collect2: ld returned 1 exit status
    Markus Dehmann, Jun 30, 2004
    #1
    1. Advertising

  2. Markus Dehmann

    JKop Guest

    Markus Dehmann posted:


    > #include <iostream>
    > #include <map>
    >
    > class California{
    > private:
    > static std::map<std::string, int> cities;
    > public:
    > California(){
    > cities.insert(std::make_pair("San Francisco", 1));
    > }
    > static bool contains(std::string city){
    > return cities.find(city) != cities.end();
    > }
    > };



    std:map<std::string,int> California::cities;


    >
    > int main(){
    > if(California::contains("San Francisco")){
    > std::cout << "SF is in CA!" << std::endl;
    > }
    > }




    Now all is well.


    -JKop
    JKop, Jul 1, 2004
    #2
    1. Advertising

  3. On Wed, 30 Jun 2004 23:08:14 GMT, JKop <> wrote:

    > Markus Dehmann posted:
    >
    >> class California{
    >> private:
    >> static std::map<std::string, int> cities;
    >> public:
    >> California(){
    >> cities.insert(std::make_pair("San Francisco", 1));
    >> }
    >> static bool contains(std::string city){
    >> return cities.find(city) != cities.end();
    >> }
    >> };

    >
    > std:map<std::string,int> California::cities;
    >
    >> int main(){
    >> if(California::contains("San Francisco")){
    >> std::cout << "SF is in CA!" << std::endl;
    >> }
    >> }

    >
    > Now all is well.


    You mean, now it compiles. But it does not work as intended: The map is
    empty. So, the constructor is actually never called, which actually makes
    sense, of course, since I never construct the object. Java has a static{}
    block for static initialization. What can I use in C++?

    And, I don't want that users of my California class have to declare the
    map California::cities. They don't have anything to do with my internal
    data structure.

    This is the sad output now (code see below):
    bash-2.05b$ g++ california.cpp
    bash-2.05b$ ./a.out
    Number of cities: 0
    SF is NOT in CA.

    How can I make it right?
    Thanks!


    #include <iostream>
    #include <map>

    class California{
    private:
    static std::map<std::string, int> cities;
    public:
    California(){
    std::cerr << "Constructor called" << std::endl;
    cities.insert(std::make_pair("San Francisco", 1));
    }
    static bool contains(std::string city){
    return cities.find(city) != cities.end();
    }
    static int getSize(){
    return cities.size();
    }
    };

    std::map<std::string,int> California::cities;

    int main(){
    std::cout << "Number of cities: " << California::getSize() <<
    std::endl;
    if(California::contains("San Francisco")){
    std::cout << "SF is in CA!" << std::endl;
    }else{
    std::cout << "SF is NOT in CA." << std::endl;
    }
    }
    Andreas Schmidt, Jul 1, 2004
    #3
  4. On Wed, 30 Jun 2004 21:44:59 -0400, Andreas Schmidt <>
    wrote:

    > On Wed, 30 Jun 2004 23:08:14 GMT, JKop <> wrote:
    >
    >> [class]
    >> std:map<std::string,int> California::cities;
    >> [int main]
    >>
    >> Now all is well.

    >
    > You mean, now it compiles. But it does not work as intended: The map is
    > empty. So, the constructor is actually never called, which actually
    > makes sense, of course, since I never construct the object. Java has a
    > static{} block for static initialization. What can I use in C++?
    >
    > And, I don't want that users of my California class have to declare the
    > map California::cities. They don't have anything to do with my internal
    > data structure.
    >
    > This is the sad output now (code see below):
    > bash-2.05b$ g++ california.cpp
    > bash-2.05b$ ./a.out
    > Number of cities: 0
    > SF is NOT in CA.
    >
    > How can I make it right?
    > Thanks!
    >
    >
    > #include <iostream>
    > #include <map>
    >
    > class California{
    > private:
    > static std::map<std::string, int> cities;
    > public:
    > California(){
    > std::cerr << "Constructor called" << std::endl;
    > cities.insert(std::make_pair("San Francisco", 1));
    > }
    > static bool contains(std::string city){
    > return cities.find(city) != cities.end();
    > }
    > static int getSize(){
    > return cities.size();
    > }
    > };
    >
    > std::map<std::string,int> California::cities;
    >
    > int main(){
    > std::cout << "Number of cities: " << California::getSize() <<
    > std::endl;
    > if(California::contains("San Francisco")){
    > std::cout << "SF is in CA!" << std::endl;
    > }else{
    > std::cout << "SF is NOT in CA." << std::endl;
    > }
    > }


    Now I think a singleton might be the best way to do this.
    Andreas Schmidt, Jul 1, 2004
    #4
  5. Markus Dehmann

    JKop Guest

    Andreas Schmidt posted:

    > Java has a static{} block for static initialization. What can I use
    > in C++?


    Just work with it like any other global variable:

    std::map<std::string,int> California::cities( ....... );


    -JKop
    JKop, Jul 1, 2004
    #5
  6. Markus Dehmann

    red floyd Guest

    Andreas Schmidt wrote:
    > On Wed, 30 Jun 2004 23:08:14 GMT, JKop <> wrote:
    >
    >> Markus Dehmann posted:
    >>
    >>> class California{
    >>> private:
    >>> static std::map<std::string, int> cities;
    >>> public:
    >>> California(){
    >>> cities.insert(std::make_pair("San Francisco", 1));
    >>> }
    >>> static bool contains(std::string city){
    >>> return cities.find(city) != cities.end();
    >>> }
    >>> };

    >>
    >>
    >> std:map<std::string,int> California::cities;
    >>
    >>> int main(){
    >>> if(California::contains("San Francisco")){
    >>> std::cout << "SF is in CA!" << std::endl;
    >>> }
    >>> }

    >>
    >>
    >> Now all is well.

    >
    >
    > You mean, now it compiles. But it does not work as intended: The map is
    > empty. So, the constructor is actually never called, which actually
    > makes sense, of course, since I never construct the object. Java has a
    > static{} block for static initialization. What can I use in C++?
    >
    > And, I don't want that users of my California class have to declare the
    > map California::cities. They don't have anything to do with my internal
    > data structure.
    >
    > This is the sad output now (code see below):
    > bash-2.05b$ g++ california.cpp
    > bash-2.05b$ ./a.out
    > Number of cities: 0
    > SF is NOT in CA.
    >
    > How can I make it right?
    > Thanks!
    >
    >
    > #include <iostream>
    > #include <map>
    >
    > class California{
    > private:
    > static std::map<std::string, int> cities;
    > public:
    > California(){
    > std::cerr << "Constructor called" << std::endl;
    > cities.insert(std::make_pair("San Francisco", 1));
    > }
    > static bool contains(std::string city){
    > return cities.find(city) != cities.end();
    > }
    > static int getSize(){
    > return cities.size();
    > }
    > };
    >
    > std::map<std::string,int> California::cities;
    >
    > int main(){
    > std::cout << "Number of cities: " << California::getSize() <<
    > std::endl;
    > if(California::contains("San Francisco")){
    > std::cout << "SF is in CA!" << std::endl;
    > }else{
    > std::cout << "SF is NOT in CA." << std::endl;
    > }
    > }


    Where did you ever create an object of class California? The only place
    that something gets added to California::cities is in the constructor
    for California. Since you never construct a California object, it's
    perfectly correct (as written) for California::cities to be empty.
    red floyd, Jul 1, 2004
    #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. Alvin Bruney

    Threads.. Session var lost, App var ok

    Alvin Bruney, Dec 2, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    360
    rooster575
    Dec 2, 2003
  2. Siemel Naran
    Replies:
    4
    Views:
    807
    Micah Cowan
    Jan 12, 2005
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,850
    Smokey Grindel
    Dec 2, 2006
  4. dolphin
    Replies:
    3
    Views:
    1,344
    Pete Becker
    Dec 5, 2007
  5. blangela
    Replies:
    8
    Views:
    664
    Erik Wikström
    Sep 26, 2008
Loading...

Share This Page