Static members and inheritance

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alex

    Static members and inheritance

    Hello. I want to manage a class hierarchy with a static member (a
    vector) in which some strings are stored depending on the Class:

    class Base { // Abstract
    ....
    typedef std::vector<std ::string> nameVector_t;
    public:
    const nameVector_t& GetNames() { return names; }
    protected:
    virtual void SetNames()=0,
    static nameVector_t names;
    };

    class House : public Base {

    virtual void SetNames() {
    names.push_back ("Door");
    names.push_back ("Window");
    names.push_back ("Roof");
    }

    };


    int main()
    {
    Base* p = new House;
    p->SetNames();
    std::cout << p->GetNames[1] << std::endl; // Should print "Window"
    }


    Is this OK? If not, how can I do something similiar?

    Thanks!

  • n.luke.meyers@gmail.com

    #2
    Re: Static members and inheritance

    The call to p->SetNames is illegal because that member function is
    protected within the enclosing context. I am also pretty sure you
    can't index into the GetNames function -- did you leave out some
    parens? And ISTR that std::vector::op erator[] is non-const, right? So
    you couldn't apply it to a const& like you're evidently trying to do.

    Unless you plan to further inherit from House, House::SetNames need not
    be virtual. Only the base class's member function needs that. Also,
    it is illegal to declare it as private, as you have, since it is
    protected in Base.

    If SetNames is going to store strings in Base::names based only on the
    class, not on member data, you should strongly consider making it a
    static member function.

    If you address these issues, your code should function as intended. I
    think there are probably some better design choices that could be made
    to accomplish the same or a similar result, though, depending on the
    needs of the actual application. For example, if you intend to call
    SetNames frequently, it would be more sensible to just update a
    reference rather than performing vector manipulations. If the values
    are known at compile time, take advantage. I'd have to know more about
    what you're trying to do, though -- I don't see how this vector of
    strings is going to help you "manage a class hierarchy."

    L

    Comment

    • Alex

      #3
      Re: Static members and inheritance

      Thanks for your response.

      I wrote that code as an example in the previous message, it is not my
      code, so there may be some errors which don't concern to what I was
      trying to do.

      That names are know at compile time and don't change duringe the
      application. I had though of something similar to what you say...

      class Base {
      public:
      virtual GetName(int id)=0;
      }

      class House {
      GetName(int id) {
      switch(id) {
      case 1: return "Door"
      case 2: return "Window"
      ...
      }
      }

      But that way you have to redefine GetName for each subclass, instead of
      inserting some string in a vector.

      What do you think?

      Comment

      • Alex

        #4
        Re: Static members and inheritance

        I meant

        ....
        virtual const char* GetName(int id)=0;
        ....

        Comment

        • Luke Meyers

          #5
          Re: Static members and inheritance

          I think this is getting closer to what you want. This will run a lot
          faster and expresses your intent more clearly. If you don't want to
          redefine GetName for every subclass, don't make it pure virtual, just
          make it virtual and provide a default implementation. You'll have to
          decide what constitutes appropriate default behavior, and what you do
          if the user requests a name from an invalid index. Something like the
          following:

          #include <string>

          class Base {
          public:
          virtual std::string const& getName(unsigne d int id) { return
          "Default"; }
          }; // <-- don't forget semicolon here

          class House : public Base {
          public:
          std::string const& GetName(unsigne d int id) { // Make this virtual,
          too, if you plan to inherit further from House
          switch(id) {
          case 1:
          // . . .
          break;
          default:
          return Base::getName(i d);
          }
          }
          };

          Also, you should use real strings (as above), not char* (as in your
          other follow-up post). Probably also an enum for the switch, etc.
          That'll get you to about where you want to be. I'm still not convinced
          it's the best approach, but it's at least straightforward and should do
          what you want.

          Luke

          Comment

          • Alex

            #6
            Re: Static members and inheritance

            I am writing an application which draws objects using OpenGL. Objects
            are editable with some dialogs and I need every object to be able to
            identify its parts. The dialog class ask the object being edited for
            its part names and some other things. That's why I need a generic way
            of asking an object for its part number x.

            Thanks for your help.

            Comment

            • Luke Meyers

              #7
              Re: Static members and inheritance

              For that purpose, I would suggest that a random-indexing idiom is a
              poor fit. Generally for "for each" behavior, you don't care what
              particular index is involved, and you're better off if you can avoid
              exposing that index in your code. Are the parts you refer to objects
              themselves? If so, I would recommend the following:

              struct Part {
              virtual std::string getName() = 0; // possibly static, if same for
              all members of a given subclass
              };

              class Base {
              protected:
              std::vector<Par t> parts;
              };

              Then you can add methods to base which loop over the parts and perform
              necessary operations. If you need the list of part names, use
              std::transform onto a vector of strings. There are a lot of directions
              you can take this, but this is where I'd start. If a part is an
              important thing in your program and has associated state (its name),
              why not represent it as an object? Forcing the enclosing object to
              maintain that state produces unnecessary coupling.

              Luke

              Comment

              • Jim Langston

                #8
                Re: Static members and inheritance

                "Alex" <acamposr@gmail .com> wrote in message
                news:1135424637 .291974.317890@ g14g2000cwa.goo glegroups.com.. .[color=blue]
                > Hello. I want to manage a class hierarchy with a static member (a
                > vector) in which some strings are stored depending on the Class:
                >
                > class Base { // Abstract
                > ...
                > typedef std::vector<std ::string> nameVector_t;
                > public:
                > const nameVector_t& GetNames() { return names; }
                > protected:
                > virtual void SetNames()=0,
                > static nameVector_t names;
                > };
                >
                > class House : public Base {
                >
                > virtual void SetNames() {
                > names.push_back ("Door");
                > names.push_back ("Window");
                > names.push_back ("Roof");
                > }
                >
                > };
                >
                >
                > int main()
                > {
                > Base* p = new House;
                > p->SetNames();
                > std::cout << p->GetNames[1] << std::endl; // Should print "Window"
                > }
                >
                >
                > Is this OK? If not, how can I do something similiar?
                >
                > Thanks!
                >[/color]

                I'm not quite positive what you are trying to do here, but in this case why
                don't you just pass the array index into GetNames itself?

                std::string GetName( int Index ) const { if ( Index < names.length() )
                return names[Index] else return ""; }

                ( it may be names.count() for vectors, I don't remember )


                Comment

                • Alex

                  #9
                  Re: Static members and inheritance

                  Because I want names to be a static member, and that's the main
                  discussion here. I want it to be static but different for each subclass.

                  Comment

                  Working...