Thread: Initializing members of base class

  1. #1
    The larch
    Join Date
    May 2006
    Posts
    3,573

    Initializing members of base class

    I can't understand why this piece of code (simplified example) would produce an error:

    Code:
    #include <string>
    class B
    {
        public:
            B(const std::string& s);
        protected:
            std::string str;
            std::string modified_str;
    };
    
    class D: public B
    {
        public:
            D(const std::string& s);
    };
    
    B::B(const std::string& s): str(s) {}
    
    D::D(const std::string& s): 
        B(s),
        modified_str(str)
    {
        //modified_str = str;
    }
    
    int main(){}
    Error message with MingW:
    D:\Untitled1.cpp: In constructor `D::D(const std::string&)':
    D:\Untitled1.cpp:21: error: class `D' does not have any field named `modified_str'
    MS VC 2005 Express compiler also mentions that neither D nor B has a member called modified_str.

    Trying to use the scope operator produces a different error (expecting class name before "(").

    However, the commented out code compiles nicely.

    (In real use I won't know what B::str will be before the base constructor finishes. At this point it is up to the derived classes to decide how to initialize modified_str - some would call another function to mutate str first, other would leave it as it is.)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Because members are constructed in the constructor of the class they are part of. Even if you leave them out of the initialization list they are still constructed silently. So by putting it into the initializer list of the derived class, you would be calling the constructor for modified_str twice which of course isn't allowed. That's why they only allow you to initialize direct members. The commented out code works because you can assign to members as many times as you want.

    Normally you would have a base class constructor that took an initial value for the member and the derived class would pass a value to it for initialization. If that doesn't make sense for your situation because the value you would pass relies on str, then asignment in the constructor seems fine to me.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Ah, thanks.

    Normally you would have a base class constructor that took an initial value for the member and the derived class would pass a value to it for initialization.
    Right, except here derived class can't do it, because it all depends on what the Base class does first on the argument that is passed for object construction.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Yeah I realized that just after I posted. I think assignment in the constructor is fine. Maybe somebody else can think of a way to use initialization, but if they can't I doubt it's a big deal.

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    There is probably nothing else to do. The design sucks somewhat but it gets the specific job done and is not meant to be extensible.

    The base class is there just to provide common functionality for two derived classes that are mostly very similar but need to do some things somewhat differently in a way that is hard to program just with special-case ifs (logic is widely different for some methods).

    Understanding the parameters at creation is part of the common things that the base class provides.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Also, don't forget to add a virtual destructor in the base class. If a derived class adds a destructor later, you could end up with a resource leak if the base has no virtual destructor.
    Everybody always forgets to make a virtual destructor...

  7. #7
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    Quote Originally Posted by cpjust View Post
    Also, don't forget to add a virtual destructor in the base class. If a derived class adds a destructor later, you could end up with a resource leak if the base has no virtual destructor.
    Only if the class is to be used polymorphically and delete'd via a base-class pointer (And then its an issue of undefined behaviour, rather than a memory leak)

    Everybody always forgets to make a virtual destructor...
    I don't know about "forgets" - oftentimes its not necessary (In this case, the base class has no virtual functions, so its unlikely to be used polymorphically).

    read here: http://www.parashift.com/c++-faq-lit....html#faq-20.7
    Last edited by Bench82; 08-23-2007 at 01:44 PM.

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    The class is not going to be used polymorphically. The derived classes have some members that take different arguments and don't follow a uniform interface. (It might be refactored at some point but it doesn't seem necessary.)

    I was just completely mislead by the compiler error and wondered why I can't use an initializer list...
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 11-17-2008, 01:00 PM
  2. Virtual base class
    By George2 in forum C++ Programming
    Replies: 7
    Last Post: 03-14-2008, 07:45 AM
  3. Read-only class members
    By kidburla in forum C++ Programming
    Replies: 4
    Last Post: 10-14-2006, 12:52 PM
  4. Private Static class members
    By earth_angel in forum C++ Programming
    Replies: 13
    Last Post: 08-29-2005, 06:37 AM