Thread: Inheritance and construction question about members

  1. #1
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665

    Inheritance and construction question about members

    Hello All,

    I've been reading up a lot on C++ and I'm starting to really appreciate the language. I like a lot of what it does and what it can do even though it may never actually help me mesh. Actually, I think it will because I want to write a hybrid mesh using tetrahedrons and what do you call it when it has 6 faces? A hexahedron? Yeah, a hexahedron.

    Anyway, I was reading the learncpp.com tutorials and I have a question about how this guy does his construction through inheritance vs. direct assignment.

    For example, which is better in the eyes of an employer or an experienced C++ programmer?

    Code:
    class animal {
    
    
       protected :
    
    
          string aniName;
    
    
       public :
    //This is my preference of construction
          animal(string name) {  
             aniName = name;
          }
    
    
          string getName(void) {
             return aniName;
          }
    
    
          virtual const char* speak(void) = 0;
    };
    vs.
    Code:
    class animal {
    
    
       protected :
    
    
          string aniName;
    
    
       public :
    //This is the method I saw
          animal(string name) : aniName(name) { }
    
    
          string getName(void) {
             return aniName;
          }
    
    
          virtual const char* speak(void) = 0;
    };
    They both do the same thing and yet I'm confused. I'm imagining that when animal's constructor is called, one of its members inherits what the construction call was fed as input. So before animal is constructed, its member is first constructed and initialized?

    Is there any benefit to initializing members through inheritance over direct assignment or is it a syntactical preference? I only ask because I'm trying to learn the best C++ practices.

    Those that recognize my username should hopefully be happy that I'm no longer using 'struct' everywhere and I'm using more of the STL.

    Btw: I read up on abstract base classes and omg, it's soooooooooo cool! It makes everything idiot-proof when using polymorphic class systems. And omg, I'm beginning to master the jargon! Take that, C++ creators, physicists can do it too!

  2. #2
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    They both do the same thing and yet I'm confused. I'm imagining that when animal's constructor is called, one of its members inherits what the construction call was fed as input. So before animal is constructed, its member is first constructed and initialized?
    Correct. This is known as an initialization list, and it actually has nothing to do with inheritance (I can see where this idea stems from, since the syntax is slightly similar).

    Initialization lists are preferable to simple assignment in the body of the constructor (i hesitate to claim this is _always_ the case, there might be some strange edge case where this isn't the case). You will need initialization lists when you have reference member variables or const member variables, so get used to them.

    Edit: Happy to see you using classes instead of structs, welcome to the dark side.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  3. #3
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Lol thank you for the reply. An 'initalization list', weird. But I can dig it.

    Also, I love your signature. I like to think of my undergraduate math abilities in a binary way, pre-QM and post-QM. My math skills were waaaaaaaay low and, boy, was there ever a learning curve but now I feel all smart about linear algebra and stuffs.

  4. #4
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by MutantJohn View Post
    Lol thank you for the reply. An 'initalization list', weird. But I can dig it.
    The reason it is called this is that you can chain the initializations together in a chain like so:

    Code:
    constructor_name(int arg ......) : member_variable(val), member_variable2(val), member_variable3(val)
    ...and so on. Please note that the initialization occurs in the order the member variables are declared in the class, NOT in the order they are placed in the initalization list.
    GCC has an option to remind you of this if you screw up the order: -Wreorder

    Also, I love your signature. I like to think of my undergraduate math abilities in a binary way, pre-QM and post-QM. My math skills were waaaaaaaay low and, boy, was there ever a learning curve but now I feel all smart about linear algebra and stuffs.
    I'm sorry to disappoint you, i know next to nothing about quantum physics. My signature is a piem.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The former, because frankly put, it's just more efficient and sometimes it's also required (it's required if the member does not provide a default constructor [a constructor that takes no arguments]).
    It's more efficient in terms that if you do it your way, it will possibly allocate resources, then have to allocate more resources and copy data over and get rid of old resources, while if you do it the former way, you tell the object extra information, which means it can be more efficient.

    I'm also going to add:
    - Consider passing arguments by const reference. It's more efficient since it avoids copying. Beware that this may conflict with move semantics in C++11 (it may or may not copy). But that's for a later lesson.
    - Getters should be marked as const because they should not modify the object. If they must modify the object, then ask yourself if it really is correct. Most likely you have a design issue. Sometimes getter must modify the object, and in such cases, the mutable keyword comes in handy.
    - You don't need to spell out "void" in the parameter lists. It's distracting and adds nothing of value.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Lol what's a "getter"? And what's "mutable"? Like, how would I modify my code to what you're saying? It's a pretty small class so I'm not sure what I'm supposed to change (aside from removing the "void" word).

    Also, wouldn't it be faster to simply tell the compiler that the function receives no arguments instead of letting it figure it out on its own?

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    A getter is a function that returns some information from a class, like your getName.
    mutable is a keyword. Google it.
    You may want to google "const correctness." I'm pretty sure there are many sites out there explaining exactly what it is. Once you know what it is, it should be pretty easy to modify your code.
    Ah, but you misunderstand C++. Unlike C, you must explicitly declare that a function can take a variable amount of arguments. Leaving the parameter list empty (ie no void) means that it takes exactly 0 arguments.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Okay, so I will be reading up on const correctness (I found this site, Const-Correctness in C++ so we'll have to see) but I was messing around with this whole polymorphism thing and I have some questions. Namely, let's first look at my abstracted polymorphic class implementation (omg, the jargon... I - I love it, I sound so smart) :

    Code:
    #include <iostream>
    #include <string>
    
    
    using std::string;
    using std::cout;
    using std::endl;
    
    
    class animal {
    
    
       protected :
    
    
          const string aniName;
    
    
       public :
    
    
          animal(const string name) : aniName(name) { }
    
    
          const string getName(void) {
             return aniName;
          }
    
    
          virtual const char* speak(void) = 0;
    };
    
    
    class cow : public animal {
    
    
       public :
    
    
          cow(const string name) : animal(name) { }
    
    
          virtual const char* speak(void) {
             return "\'Cow says 'moo', mother****er!\'";
          }
    };
    
    
    int main(void) {
    
    
       cow taurus("Sadie");
    
    
       animal & beast = taurus;
    
    
       cout << beast.getName() << " says, " << beast.speak() << endl;
    
    
       return 0;
    }
    First off, am I now using the proper const correctness? I basically just plugged it in anywhere I could find and compiling with "g++ -Wall -Wextra" gave me no errors or warnings and valgrind was quiet as well.

    I don't really get the point of const correctness but I guess it does show a higher degree of skill to use it because it shows that the code does indeed work exactly as was intended.

    Now, my next question is, when I declare beast as a reference the code works but if I simply declare an animal class named "beast" and initialize it to taurus, I get all these compilation errors. I get that with references a variables will literally become what you're referencing it to but why can't I just declare beast and set it to taurus? Or do I need to create it as an animal pointer and point it to the address of my taurus variable?

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    since speak function (as well as getName) does not change this - it should be declared const. otherwise you will not be able to call it from the const object.

    Try to create const cow and const reference to cow to check that everything works as it should
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  10. #10
    Tweaking master Aslaville's Avatar
    Join Date
    Sep 2012
    Location
    Rogueport
    Posts
    528
    Now, my next question is, when I declare beast as a reference the code works but if I simply declare an animal class named "beast" and initialize it to taurus, I get all these compilation errors. I get that with references a variables will literally become what you're referencing it to but why can't I just declare beast and set it to taurus? Or do I need to create it as an animal pointer and point it to the address of my taurus variable?
    class animal has pure virtual functions that means that it can only act as a base class.
    A reference to an object of the base class can refer to either and object of the base class or an object of a derived class.Edit :Well that is to some extent the heart of OOP and nothing comprehensive enough can be posted here about that,..you can only get it from a book and I am sure you will get it as you wade through the book you are reading.
    Last edited by Aslaville; 08-23-2013 at 01:13 PM.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by MutantJohn View Post
    Okay, so I will be reading up on const correctness (I found this site, Const-Correctness in C++ so we'll have to see) but I was messing around with this whole polymorphism thing and I have some questions. Namely, let's first look at my abstracted polymorphic class implementation (omg, the jargon... I - I love it, I sound so smart) :
    I don't know if you should rely on that article. It seems more like a C programmer than a C++ programmer. If you see people using C strings or a lot of new and little STL, then it's a good bet it's not a good C++ programmer.

    First off, am I now using the proper const correctness? I basically just plugged it in anywhere I could find and compiling with "g++ -Wall -Wextra" gave me no errors or warnings and valgrind was quiet as well.
    Not exactly.
    Separate const variables, const parameters and const functions.
    You basically said the variable should be const which means that you cannot ever change it for as long as the class lives. You probably didn't want that (try adding a function that changes the value of that variable and you'll get an error).
    You probably wanted to mark the functions as const. That basically means they can't change any variables in the class (unless they're marked as mutable).

    I don't really get the point of const correctness but I guess it does show a higher degree of skill to use it because it shows that the code does indeed work exactly as was intended.
    It catches more bugs at compile time. Imagine you calling a function which you do not expect to change a variable but you pass via reference.
    Well, what if it changes the variable (by accident)? You'll find out at runtime (hopefully) or it will be a bug that is never discovered. Ouch. If you mark it as const, the compiler will complain 100% of the time. The bug will never happen.

    Now, my next question is, when I declare beast as a reference the code works but if I simply declare an animal class named "beast" and initialize it to taurus, I get all these compilation errors. I get that with references a variables will literally become what you're referencing it to but why can't I just declare beast and set it to taurus? Or do I need to create it as an animal pointer and point it to the address of my taurus variable?
    Abstract classes (classes with at least one pure virtual function) cannot be instantiated. You can't create them.
    You can declare pointers and references to them because you're not actually creating instances of them if you do.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Okay, is this a much more proper use of const correctness? Btw, thank you guys for all your help. I really am trying to learn this stuff.
    Code:
    #include <iostream>
    #include <string>
    
    
    using std::string;
    using std::cout;
    using std::endl;
    
    
    class animal {
    
    
       protected :
    // Does this need to be const? Idt so...
          string aniName;
    
    
       public :
    // This is everything cow is allowed to inherit and modify, right?
          animal(string name) : aniName(name) { }
    //getName is not allowed to change any member of the class now, correct?
          string getName(void) const {
             return aniName;
          }
    // We return a const char* which seems to be logically equivalent to
    // a string and speak() is no longer allowed to change any members
    // as well.
          virtual const char* speak(void) const = 0;
    };
    
    
    class cow : public animal {
    
    
       public :
    
    
          cow(string name) : animal(name) { }
    // This version of speak must match the base version, right? As such, it too
    // is no longer allowed to change any members of the class.
          virtual const char* speak(void) const {
             return "\'Cow says 'moo', mother........er!\'";
          }
    };
    
    
    int main(void) {
    // Much like irl, my Taurus is constant in my life
       const cow taurus("Sadie");
    // And I am a constant beast as well.
       const animal & beast = taurus;
    
    
       cout << beast.getName() << " says, " << beast.speak() << endl;
    
    
       return 0;
    }

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    This is much better.
    You probably take to heart to pass non-primitives (classes, structs) by const reference (ie const T&). It's pretty much recommended practice pre-C++11 (in C++11, it's a little more complicated).
    Last edited by Elysia; 08-23-2013 at 02:06 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by MutantJohn View Post
    Okay, is this a much more proper use of const correctness? Btw, thank you guys for all your help. I really am trying to learn this stuff.
    <snip>
    Since you're letting the constructor of animal handle the initialization of the name string, there is actually no reason for it to be protected, make it private and it will still work. If you had chosen to let the constructors of the derived classes handle the initialization of name then it would have to be protected.

    Also, to add to what Elysia said about const-correctness: Using the const keyword is a short and concise way to communicate to someone using your classes that the function will not alter the parameters, or alter the state of the object. Without using the const keyword, all you could do is promise not to alter anything in the documentation and then the programmer using your library/code would just have to take your word for it.

    Similarly, if you set out writing a complex function and you know it should not alter the parameters/object then you can make it const and the compiler will generate an error if you end up accidentally trying to change a value.

    It's pretty much recommended practice pre-C++11 (in C+11, it's a little more complicated).
    Care to elaborate? I've yet to get my feet properly wet with C++11.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Neo1 View Post
    Care to elaborate? I've yet to get my feet properly wet with C++11.
    c++ - Is pass-by-value a reasonable default in C++11? - Stack Overflow
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Protected Members and Templated Inheritance
    By Axl in forum C++ Programming
    Replies: 6
    Last Post: 09-22-2011, 10:31 AM
  2. Data members in inheritance
    By DarthMaster84 in forum C++ Programming
    Replies: 1
    Last Post: 04-20-2010, 02:37 AM
  3. equal members in BST question..
    By transgalactic2 in forum C Programming
    Replies: 4
    Last Post: 10-30-2008, 01:32 PM
  4. static members construction
    By glUser3f in forum C++ Programming
    Replies: 3
    Last Post: 11-09-2003, 09:58 PM
  5. inheritance from classes own members?
    By atapi103 in forum C++ Programming
    Replies: 2
    Last Post: 09-02-2003, 10:19 PM