Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. inherited classes and const members

inherited classes and const members

Scheduled Pinned Locked Moved Unsolved C++ Gurus
27 Posts 5 Posters 12.5k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #1

    Hi all -

    I'm sure this isn't really a guru-level question, but after years of C++ programming, I've finally come across a use for inheritance, and I'm having trouble.

    I want to create a base class that contains some constant members, and from this class derive a subclass that would have different values for those members. Something like this:

    class Button
    {
    protected:
        const TickType_t READ_INTERVAL;
    };
    
    class ButtonRTFM: public Button {}
    Button::Button(Tasks *tasks) 
        :    READ_INTERVAL (100)
    {}
    
    ButtonRTFM::ButtonRTFM(Tasks *tasks) 
        : )  READ_INTERVAL (500) 
    {}
    

    But this gives me an error about READ_INTERVAL being non-static (in the derived class). So obviously I don't understand how this is supposed to be done; can someone give me some guidance?

    Thanks...

    Kent-DorfmanK JonBJ 2 Replies Last reply
    0
    • mzimmersM mzimmers

      Hi all -

      I'm sure this isn't really a guru-level question, but after years of C++ programming, I've finally come across a use for inheritance, and I'm having trouble.

      I want to create a base class that contains some constant members, and from this class derive a subclass that would have different values for those members. Something like this:

      class Button
      {
      protected:
          const TickType_t READ_INTERVAL;
      };
      
      class ButtonRTFM: public Button {}
      Button::Button(Tasks *tasks) 
          :    READ_INTERVAL (100)
      {}
      
      ButtonRTFM::ButtonRTFM(Tasks *tasks) 
          : )  READ_INTERVAL (500) 
      {}
      

      But this gives me an error about READ_INTERVAL being non-static (in the derived class). So obviously I don't understand how this is supposed to be done; can someone give me some guidance?

      Thanks...

      Kent-DorfmanK Offline
      Kent-DorfmanK Offline
      Kent-Dorfman
      wrote on last edited by Kent-Dorfman
      #2

      ButtonRTFM::ButtonRTFM(Tasks *tasks)
      : ) READ_INTERVAL (500)
      {}

      what's with this syntax? It doesn't look right. ")" after the colon?

      and if ButtonRTFM::ButtonTRFM is the constructor of hte subclass then you should call the parent constructor too.

      // ------------------------------------------------------------------
      ButtonRTFM::ButtonTRFM(Tasks *tasks): Button(tasks), READ_INTERVAL (500)  {
      }
      

      I'd also suggest NOT making READ_INTERVAL const because you are setting it in both the base constructor, and the subclass constructor as an overriden value.

      If you meet the AI on the road, kill it.

      1 Reply Last reply
      0
      • mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by
        #3

        Yeah, you're right...sloppy cut-and-paste on my part.

        class Button
        {
        protected:
            const TickType_t READ_INTERVAL;
        };
        
        class ButtonRTFM: public Button {}
        Button::Button(Tasks *tasks) 
            :    READ_INTERVAL (100)
        {}
        
        ButtonRTFM::ButtonRTFM(Tasks *tasks) 
            :  READ_INTERVAL (500) 
        {}
        

        Sorry about that...

        kshegunovK 1 Reply Last reply
        0
        • Kent-DorfmanK Offline
          Kent-DorfmanK Offline
          Kent-Dorfman
          wrote on last edited by
          #4

          and oh, you cannot initialize a const variable in the base class from within the subclass. you have to create a base class constructor that sets it , and chain that constructor in the subclass initialization as I showed above.

          If you meet the AI on the road, kill it.

          1 Reply Last reply
          3
          • mzimmersM mzimmers

            Yeah, you're right...sloppy cut-and-paste on my part.

            class Button
            {
            protected:
                const TickType_t READ_INTERVAL;
            };
            
            class ButtonRTFM: public Button {}
            Button::Button(Tasks *tasks) 
                :    READ_INTERVAL (100)
            {}
            
            ButtonRTFM::ButtonRTFM(Tasks *tasks) 
                :  READ_INTERVAL (500) 
            {}
            

            Sorry about that...

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by kshegunov
            #5

            Also some floating types and missing declaration. Anyways, READ_INTERVAL isn't part of ButtonRTFM, so you can't use it in the initializer list. If you want to do that, you need to delegate it through the parent's constructor. E.g.

            class Button
            {
            public:
                Button();
            
            protected:
                Button(TickType_t);
            
                const TickType_t READ_INTERVAL;
            };
            
            Button::Button()
                : Button(100)
            {
            }
            
            Button::Button(TickType_t interval)
                : READ_INTERVAL(interval)
            {
            }
            
            class ButtonRTFM : public Button
            {
            public:
                ButtonRTFM();
            };
            
            ButtonRTFM::ButtonRTFM()
                : Button(500)
            {
            }
            

            Read and abide by the Qt Code of Conduct

            mzimmersM 1 Reply Last reply
            3
            • Kent-DorfmanK Offline
              Kent-DorfmanK Offline
              Kent-Dorfman
              wrote on last edited by Kent-Dorfman
              #6

              StackOverflow thread about this very issue:

              If you meet the AI on the road, kill it.

              1 Reply Last reply
              0
              • mzimmersM mzimmers

                Hi all -

                I'm sure this isn't really a guru-level question, but after years of C++ programming, I've finally come across a use for inheritance, and I'm having trouble.

                I want to create a base class that contains some constant members, and from this class derive a subclass that would have different values for those members. Something like this:

                class Button
                {
                protected:
                    const TickType_t READ_INTERVAL;
                };
                
                class ButtonRTFM: public Button {}
                Button::Button(Tasks *tasks) 
                    :    READ_INTERVAL (100)
                {}
                
                ButtonRTFM::ButtonRTFM(Tasks *tasks) 
                    : )  READ_INTERVAL (500) 
                {}
                

                But this gives me an error about READ_INTERVAL being non-static (in the derived class). So obviously I don't understand how this is supposed to be done; can someone give me some guidance?

                Thanks...

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #7

                @mzimmers said in inherited classes and const members:

                but after years of C++ programming, I've finally come across a use for inheritance

                Blimey, my friend, this is really the first time you've you've found a use for inheritance?!! :)

                J.HilkJ mzimmersM 2 Replies Last reply
                2
                • JonBJ JonB

                  @mzimmers said in inherited classes and const members:

                  but after years of C++ programming, I've finally come across a use for inheritance

                  Blimey, my friend, this is really the first time you've you've found a use for inheritance?!! :)

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  @JonB you know, we all start somewhere.

                  Before I knew better, I had duplicates of my classes in projects, with slightly different names, to have more than 1 object at a time....

                  0_1550660045864_f62ceeac-7377-4f97-97e7-0c5642ff37d2-image.png

                  thankfully that phase didn't last long.


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  2
                  • JonBJ JonB

                    @mzimmers said in inherited classes and const members:

                    but after years of C++ programming, I've finally come across a use for inheritance

                    Blimey, my friend, this is really the first time you've you've found a use for inheritance?!! :)

                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #9

                    @JonB said in inherited classes and const members:

                    Blimey, my friend, this is really the first time you've you've found a use for inheritance?!! :)

                    Perhaps it would have been more accurate to say that it's the first time I found a use for it before I started coding. There have been a few instances where I did a retrospective look at some work and thought "oh yeah..."

                    1 Reply Last reply
                    1
                    • kshegunovK kshegunov

                      Also some floating types and missing declaration. Anyways, READ_INTERVAL isn't part of ButtonRTFM, so you can't use it in the initializer list. If you want to do that, you need to delegate it through the parent's constructor. E.g.

                      class Button
                      {
                      public:
                          Button();
                      
                      protected:
                          Button(TickType_t);
                      
                          const TickType_t READ_INTERVAL;
                      };
                      
                      Button::Button()
                          : Button(100)
                      {
                      }
                      
                      Button::Button(TickType_t interval)
                          : READ_INTERVAL(interval)
                      {
                      }
                      
                      class ButtonRTFM : public Button
                      {
                      public:
                          ButtonRTFM();
                      };
                      
                      ButtonRTFM::ButtonRTFM()
                          : Button(500)
                      {
                      }
                      
                      mzimmersM Offline
                      mzimmersM Offline
                      mzimmers
                      wrote on last edited by
                      #10

                      @kshegunov thanks for the example. I'm starting to think it was a bad idea to re-use names of consts - makes for more complex code, and could be very confusing to keep straight.

                      I guess I still don't entirely understand inheritance. Why is this wrong?

                      class Base
                      {
                      protected:
                          int i;
                      };
                      
                      class Derived : public Base
                      {
                      public:
                          Derived();
                      };
                      
                      Derived::Derived() : i (1)
                      {}
                      
                      kshegunovK Kent-DorfmanK 2 Replies Last reply
                      0
                      • mzimmersM mzimmers

                        @kshegunov thanks for the example. I'm starting to think it was a bad idea to re-use names of consts - makes for more complex code, and could be very confusing to keep straight.

                        I guess I still don't entirely understand inheritance. Why is this wrong?

                        class Base
                        {
                        protected:
                            int i;
                        };
                        
                        class Derived : public Base
                        {
                        public:
                            Derived();
                        };
                        
                        Derived::Derived() : i (1)
                        {}
                        
                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #11

                        @mzimmers said in inherited classes and const members:

                        Why is this wrong?

                        Consistency in the language and/or typing. You can only use the current class' members in the initializer list to prevent you from blowing off your toe (as opposed to shooting yourself in the foot).

                        In C++ even if you don't do it explicitly the base class' default constructor is going to be called for you (this is the first thing in the initializer list). Now imagine what is supposed to happen if the base class' constructor is initializing the same variable and then you overwrite it in the derived class' initializer. Is it correct, or simply an error?

                        Even worse, suppose the base class (being badly written) expects the derived class to init the base's own privates, because why not, it's allowed ... then you're in for a treat. In principle the base class is responsible for its resources (RAII), not the derived ones. If it were the other way around, it'd be like asking a car type to make sure there's internal consistency in the machine type it derives from, why should the "car" care? It's a "machine" already, right? So everything related to the machine type should already be available out of the box for its subtypes.

                        Read and abide by the Qt Code of Conduct

                        mzimmersM 1 Reply Last reply
                        3
                        • kshegunovK kshegunov

                          @mzimmers said in inherited classes and const members:

                          Why is this wrong?

                          Consistency in the language and/or typing. You can only use the current class' members in the initializer list to prevent you from blowing off your toe (as opposed to shooting yourself in the foot).

                          In C++ even if you don't do it explicitly the base class' default constructor is going to be called for you (this is the first thing in the initializer list). Now imagine what is supposed to happen if the base class' constructor is initializing the same variable and then you overwrite it in the derived class' initializer. Is it correct, or simply an error?

                          Even worse, suppose the base class (being badly written) expects the derived class to init the base's own privates, because why not, it's allowed ... then you're in for a treat. In principle the base class is responsible for its resources (RAII), not the derived ones. If it were the other way around, it'd be like asking a car type to make sure there's internal consistency in the machine type it derives from, why should the "car" care? It's a "machine" already, right? So everything related to the machine type should already be available out of the box for its subtypes.

                          mzimmersM Offline
                          mzimmersM Offline
                          mzimmers
                          wrote on last edited by
                          #12

                          @kshegunov good explanation, and it makes sense (though it's a little odd that you can't initialize a member, but you can assign to it, but...no matter).

                          So, what is considered best practices for a situation like this, where you want modified (yet constant) parameters in a subclass?

                          J.HilkJ 1 Reply Last reply
                          0
                          • mzimmersM mzimmers

                            @kshegunov good explanation, and it makes sense (though it's a little odd that you can't initialize a member, but you can assign to it, but...no matter).

                            So, what is considered best practices for a situation like this, where you want modified (yet constant) parameters in a subclass?

                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by J.Hilk
                            #13

                            @mzimmers
                            see @kshegunov post, 8 post prior
                            @kshegunov said in inherited classes and const members:

                            class Button
                            {
                            public:
                                Button();
                            
                            protected:
                                Button(TickType_t);
                            
                                const TickType_t READ_INTERVAL;
                            };
                            
                            Button::Button()
                                : Button(100)
                            {
                            }
                            
                            Button::Button(TickType_t interval)
                                : READ_INTERVAL(interval)
                            {
                            }
                            
                            class ButtonRTFM : public Button
                            {
                            public:
                                ButtonRTFM();
                            };
                            
                            ButtonRTFM::ButtonRTFM()
                                : Button(500)
                            {
                            }
                            

                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            mzimmersM 1 Reply Last reply
                            1
                            • J.HilkJ J.Hilk

                              @mzimmers
                              see @kshegunov post, 8 post prior
                              @kshegunov said in inherited classes and const members:

                              class Button
                              {
                              public:
                                  Button();
                              
                              protected:
                                  Button(TickType_t);
                              
                                  const TickType_t READ_INTERVAL;
                              };
                              
                              Button::Button()
                                  : Button(100)
                              {
                              }
                              
                              Button::Button(TickType_t interval)
                                  : READ_INTERVAL(interval)
                              {
                              }
                              
                              class ButtonRTFM : public Button
                              {
                              public:
                                  ButtonRTFM();
                              };
                              
                              ButtonRTFM::ButtonRTFM()
                                  : Button(500)
                              {
                              }
                              
                              mzimmersM Offline
                              mzimmersM Offline
                              mzimmers
                              wrote on last edited by
                              #14

                              @J.Hilk I recognize kshegunov's suggestion as the correct answer, assuming I was going to stubbornly insist on trying to implement this as I originally described. What I meant to ask was, should I be taking a different approach to this problem? Perhaps multiple true const definitions outside the class, and the subclasses have their own members instead of re-using the base class'? Just thinking out loud here.

                              kshegunovK 1 Reply Last reply
                              0
                              • mzimmersM mzimmers

                                @J.Hilk I recognize kshegunov's suggestion as the correct answer, assuming I was going to stubbornly insist on trying to implement this as I originally described. What I meant to ask was, should I be taking a different approach to this problem? Perhaps multiple true const definitions outside the class, and the subclasses have their own members instead of re-using the base class'? Just thinking out loud here.

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by kshegunov
                                #15

                                @mzimmers said in inherited classes and const members:

                                What I meant to ask was, should I be taking a different approach to this problem?

                                Perhaps, but let me rephrase your question as it sounds to me (warning metaphor following):

                                I want to drive a nail, how heavy a hammer do I need?

                                The obvious answer would be: "Well, depends on the nail". That is to say, what's your context?
                                From what we've discussed so far we have a dummy class with a constant - nothing more than a means to an end. So what's your end goal? Where, how are you going to use it and why you need that constant?

                                Read and abide by the Qt Code of Conduct

                                mzimmersM 1 Reply Last reply
                                2
                                • kshegunovK kshegunov

                                  @mzimmers said in inherited classes and const members:

                                  What I meant to ask was, should I be taking a different approach to this problem?

                                  Perhaps, but let me rephrase your question as it sounds to me (warning metaphor following):

                                  I want to drive a nail, how heavy a hammer do I need?

                                  The obvious answer would be: "Well, depends on the nail". That is to say, what's your context?
                                  From what we've discussed so far we have a dummy class with a constant - nothing more than a means to an end. So what's your end goal? Where, how are you going to use it and why you need that constant?

                                  mzimmersM Offline
                                  mzimmersM Offline
                                  mzimmers
                                  wrote on last edited by
                                  #16

                                  @kshegunov fair enough. I'm working on an embedded application. The host device originally called for a push button (a real button, not a QPushButton). Now it is being modified to have 2 buttons. For each button, I need to poll a GPIO, perform debouncing, and report when a valid press has occurred.

                                  Except for a few arguments for the debouncing algorithm, the software for the buttons will be identical. So, I thought that for each button type, I'd just pass in some values at construction and leave it at that. Those values don't have to be constants, but that was my original thinking before I realized that it wasn't entirely straightforward.

                                  1 Reply Last reply
                                  0
                                  • Kent-DorfmanK Offline
                                    Kent-DorfmanK Offline
                                    Kent-Dorfman
                                    wrote on last edited by
                                    #17

                                    Have you no one there on site to preach about how evil it is to use c++ for embedded applications? non-deterministic memory management with a high probability of long term memory fragmentation, the overhead of exceptions and/or the c++ runtime?

                                    the term "embedded" has become so ambiguous in recent years. LOL

                                    To me, embedded usually mean hard RTOS, with extremely tight deterministic requirements for things like memory managment and interupt handling...not exactly the typical Qt use case.

                                    and yeah, for non-critical embedded systems I like coding in c++ too, if they'll let me. :^)

                                    PS - yell and scream until they implement the debounce in hardware. It's just a couple freaking caps and it will work flawlessly.

                                    If you meet the AI on the road, kill it.

                                    mzimmersM kshegunovK 2 Replies Last reply
                                    0
                                    • mzimmersM mzimmers

                                      @kshegunov thanks for the example. I'm starting to think it was a bad idea to re-use names of consts - makes for more complex code, and could be very confusing to keep straight.

                                      I guess I still don't entirely understand inheritance. Why is this wrong?

                                      class Base
                                      {
                                      protected:
                                          int i;
                                      };
                                      
                                      class Derived : public Base
                                      {
                                      public:
                                          Derived();
                                      };
                                      
                                      Derived::Derived() : i (1)
                                      {}
                                      
                                      Kent-DorfmanK Offline
                                      Kent-DorfmanK Offline
                                      Kent-Dorfman
                                      wrote on last edited by
                                      #18

                                      @mzimmers said in inherited classes and const members:

                                      @kshegunov thanks for the example. I'm starting to think it was a bad idea to re-use names of consts - makes for more complex code, and could be very confusing to keep straight.

                                      I guess I still don't entirely understand inheritance. Why is this wrong?

                                      class Base
                                      {
                                      protected:
                                          int i;
                                      };
                                      
                                      class Derived : public Base
                                      {
                                      public:
                                          Derived();
                                      };
                                      
                                      Derived::Derived() : i (1)
                                      {}
                                      

                                      see this -> StackOverflow

                                      If you meet the AI on the road, kill it.

                                      1 Reply Last reply
                                      0
                                      • Kent-DorfmanK Kent-Dorfman

                                        Have you no one there on site to preach about how evil it is to use c++ for embedded applications? non-deterministic memory management with a high probability of long term memory fragmentation, the overhead of exceptions and/or the c++ runtime?

                                        the term "embedded" has become so ambiguous in recent years. LOL

                                        To me, embedded usually mean hard RTOS, with extremely tight deterministic requirements for things like memory managment and interupt handling...not exactly the typical Qt use case.

                                        and yeah, for non-critical embedded systems I like coding in c++ too, if they'll let me. :^)

                                        PS - yell and scream until they implement the debounce in hardware. It's just a couple freaking caps and it will work flawlessly.

                                        mzimmersM Offline
                                        mzimmersM Offline
                                        mzimmers
                                        wrote on last edited by
                                        #19

                                        @Kent-Dorfman you did know that Reagan's out of office, right? You sound like you're almost as much of a dinosaur as I am.

                                        In seriousness, I don't disagree with your definition of embedded systems, though it is a bit limiting in the age of IoT. I think Qt is a fine platform for many embedded applications, provided that the product designer doesn't get too stingy with the hardware resources.

                                        In my case, this app is headless, so I'm not using the Qt libraries...just Creator as an editor and code browser. Better than anything else I've found so far.

                                        Kent-DorfmanK 1 Reply Last reply
                                        1
                                        • Kent-DorfmanK Kent-Dorfman

                                          Have you no one there on site to preach about how evil it is to use c++ for embedded applications? non-deterministic memory management with a high probability of long term memory fragmentation, the overhead of exceptions and/or the c++ runtime?

                                          the term "embedded" has become so ambiguous in recent years. LOL

                                          To me, embedded usually mean hard RTOS, with extremely tight deterministic requirements for things like memory managment and interupt handling...not exactly the typical Qt use case.

                                          and yeah, for non-critical embedded systems I like coding in c++ too, if they'll let me. :^)

                                          PS - yell and scream until they implement the debounce in hardware. It's just a couple freaking caps and it will work flawlessly.

                                          kshegunovK Offline
                                          kshegunovK Offline
                                          kshegunov
                                          Moderators
                                          wrote on last edited by kshegunov
                                          #20

                                          The host device originally called for a push button (a real button, not a QPushButton). Now it is being modified to have 2 buttons. For each button, I need to poll a GPIO, perform debouncing, and report when a valid press has occurred.

                                          You could use a private anonymous enum for that, e.g.:

                                          class Something
                                          {
                                          private:
                                              enum { Whatever = 300 };
                                          };
                                          

                                          I don't see any real gain in having it as a member though, probably a static for each class (basically a scoped global constant) would be more practical, e.g.:

                                          class Something
                                          {
                                          private:
                                              static const int whatever;
                                          };
                                          

                                          and don't forget to define it in the source (or use direct initialization if your compiler supports it):

                                          static const int Something::whatever = 200;
                                          

                                          @Kent-Dorfman said in inherited classes and const members:

                                          non-deterministic memory management

                                          What's non-deterministic about it?

                                          with a high probability of long term memory fragmentation

                                          I don't see how memory fragmentation has anything to do with c++. Heap allocations are calls into the kernel, they're not managed directly.

                                          the overhead of exceptions

                                          Exceptions can be disabled, and setjmp and longjmp existed for pretty much as long as computers have.

                                          and/or the c++ runtime?

                                          What would be that exactly? Constructors, destructors, operators? All of this existed before and continue to do so in C, they're just free functions. Hell even virtual methods I have seen emulated in C through function pointers ...

                                          Read and abide by the Qt Code of Conduct

                                          Kent-DorfmanK 1 Reply Last reply
                                          3

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved