CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Nov 2002
    Posts
    23

    Unhappy Variable Inheritence

    Hi
    I have an issue with variables in parent and child classes.
    Basically what I want to do is create a method in the parent class that is used within all the child classes. However the method uses a variable 'n' that I want to be different for each child class.

    How would I go about doing this? I cant seem to get it to work.
    Is there a way to override variables maybe?

    Thanks

  2. #2
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Is the type of n changing? Is the function's contents static, but
    you want only the type to change? If so, you could use a member
    template function. You can't virtual-ize these, though, so you'd
    need another approach if the functions need to be overridden
    in the derived classes.

    --Paul

  3. #3
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    If your base class function consists of mostly common code, with only a small amount differing in the derived classes you could try the Template Pattern:
    Code:
    class base
    {
    public:
        void some_function()
        {
            // do some common processing...
            variable_part();
            // more processing...
        }
    protected:
        virtual void variable_part() {}
    };
    
    class derived: public base
    {
        // ...
    protected:
        void variable_part()
        {
            // processing specific to this class
        }
    };
    of course, this can be simplified if the variable is of the same type in all classes by adding a virtual function to get the value. In this case, I would make the function in the base class pure and private:
    Code:
    class base
    {
        // .....
    
    private:
        virtual int get_n() = 0;
    };
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  4. #4
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    Provide more details

    Lil'Hasher,

    Please specify more clearly the use of n. Is n a member of the parent base-class? As Paul asked, when you say that you want n to be different for each child-class, is the type of n changing or do you mean that each child class has it's own unique instance of n?

    Paul, I get the feeling that the question might be simpler to handle than the ideas in your post.

    Sincerely,
    Chris.

    You're gonna go blind staring into that box all day.

  5. #5
    Join Date
    Nov 2002
    Posts
    23
    Hi Guys,

    Well my actual problem is that I would like to have a string variable for each derived class, each with a different length.
    However there is a method that is common to all the classes and uses this string.

    So for example

    class base{
    public:
    char name[20];

    base(char* str){
    strcpy(name, str);
    }

    //Other methods that use name
    }

    class derived: public base{
    public:
    char name[3];
    };

    I need something like that, although I dont think the above code works the way I would like it to. I've tried using "this" and other tricks but nothing seems to work. I understand Graham's suggestion....but is that the simplest way to do this??

    thanks again

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449
    I would like to have a string variable for each derived class, each with a different length
    Use std::string in the base class. This solves your problem:
    Code:
    #include <string>
    #include <iostream>
    
    class foo {
    //...
         protected:
              std::string thisString;
    
         public:
              void SetString(const std::string& s) 
              {
                    thisString = s;
              }
    
              void PrintLength() { std::cout << "Length of string is " << thisString.length() << std::endl; }
    };
    
    class fooDerived : public foo
    {
    };
    
    class fooDerived2 : public foo
    {
    };
    
    int main()
    {
        fooDerived s;
        fooDerived s2;
        s.SetString("ABCDEF");
        s2.SetString("123");
        s.PrintLength();
        s2.PrintLength();
        return 0;
    }
    For s, the length of the string is 6, for s2, the length is 3.

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Nov 2002
    Posts
    23
    is there anyway at all to do this using a character array? I was so sure it was possible and that I was just forgetting something.

    Thanks for all the help, I appreciate it

    Lil'Hash

  8. #8
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    For a char array whose size is dynamic, you'll need a char* and
    that char* will point to dynamically allocated data.
    Code:
    class Base
    {
    public:
       Base() : m_pString(0) {}
       ~Base() { if m_pString { delete [] m_pString; }
    
       void setString(const char* input)
       {
          m_pString = new char[strlen(input) + 1];
          strcpy(m_pString, input);
       }
    
    private:
       char* m_pString;
    };
    However, I strongly recommend that you use std::string because
    of all of the memory allocation you'll have to worry about with
    the approach I outlined above.

    --Paul

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by Lil'Hasher
    is there anyway at all to do this using a character array? I was so sure it was possible and that I was just forgetting something.

    Thanks for all the help, I appreciate it

    Lil'Hash
    As Paul W. pointed out, you have to manage the memory yourself. One thing Paul left out of his example is that you need to write a copy constructor and assignment operator to properly manage your class if you use char *. I will post them and you can tell me which one you feel is easier to maintain.

    First, char *
    Code:
    class Base
    {
    public:
       Base() : m_pString(0) {}
       ~Base() { if m_pString { delete [] m_pString; }
    
       void setString(const char* input)
       {
          delete [] m_pString;
          m_pString = new char[strlen(input) + 1];
          strcpy(m_pString, input);
       }
    
       Base(const Base& rhs)
       {
             setString( rhs.m_pString );
       }
     
       Base& operator = (const Base& rhs)
       {
            if ( this == &rhs )
               return *this;
           setString( rhs.m_pString )
           return *this;
       }
    
    private:
       char* m_pString;
    };
    Second std::string
    Code:
    class Base
    {
    public:
       void setString(const std::string& input)
       {
          m_String = input;
       }
    
    private:
       std::string m_String;
    };
    Now which one is more preferable and easier to maintain and understand? If you don't understand the copy constructor and assignment operator, that is more reason to use std::string.

    Again, use what's there -- std::string. It works, it is standard, doesn't need any code to manage memory, and the proper C++ way to accomplish what you are seeking. Unless there is a compelling (and really compelling) reason to use a char array, you should use std::string.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 6th, 2003 at 03:10 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured