Thread: Base Class Arrays

  1. #1
    The Defective GRAPE Lurker's Avatar
    Join Date
    Feb 2003
    Posts
    949

    Base Class Arrays

    Let's say we have an abstract class base and a class derived from it called derived. If you create a normal array of base, would it be possible to place derived objects in the array? Thanks for help!
    Do not make direct eye contact with me.

  2. #2
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    A quick program says yes.

    Code:
    #include <stdio.h>
    
    class Base
    {
    public:
      int i ;
    };
    
    class Derived : public Base
    {
    public:
       int j ;
    };
    
    int main(int argc, char *argv[])
    {
      Base base[10] ;
      Derived derived ;
      
      derived.i = 2 ;
      
      base[0] = derived; 
      
      printf( "base[0].i = %d\n", base[0].i ) ;
      
      getchar() ;	
      return 0;
    }

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    I don't think so, because the size of each object in an array must be the same, but the size of a base object may well be different thant the size of a derived object. But with virtual methods and an array of pointers to base class (all pointers have the same size, and all derived objects are base objects so this is allowable), you can create the same effect.

  4. #4
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    I thought that even if the sizes of both classes are different, the Derived class is at least guaranteed to have all the members in the Base class, so when you assign a Derived object to a Base object, you assign only the members common to them.

  5. #5
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    If the base class is abstract, then you can't have an array of them anyway.

    Dante Shamest, your example is allowed because Base is not abstract, and because you are slicing the derived-ness of the derived variable. So technically speaking, you are not placing an object of type Derived into your array, you are placing a Base object that is a copy of the Base part of your Derived object.

    That is why elad is right, in order to put derived class objects into an array that only knows about the base class (abstract or not), you must use pointers or references.

  6. #6
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Ah, I thought the OP was only talking about assigning Derived objects to Base objects, even though there would be functionality loss.

  7. #7
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Sorry, didn't mean to make it sound like I was saying you were wrong, I don't think you were. It just depends on what Lurker meant exactly.

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Let's say we have an abstract class base and a class derived from it called derived.
    Okay.

    >If you create a normal array of base
    You would get an error because you would be trying to instantiate objects of an abstract class. But assuming you meant an array of pointers to base, we'll continue.

    >would it be possible to place derived objects in the array?
    Yes it would. Of course, seeing somebody use arrays polymorphically would raise red flags for many programmers.
    My best code is written with the delete key.

  9. #9
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Prelude, when you said
    ... But assuming you meant an array of pointers to base, we'll continue.

    >would it be possible to place derived objects in the array?
    Yes it would. Of course, seeing somebody use arrays polymorphically would raise red flags for many programmers.
    It made it sound (at least to me) that you were saying that using arrays of pointers to base and taking advantage of polymorphism in that way would raise red flags.

    But you meant that using arrays of the base class objects themselves would raise red flags, right? And it is perfectly natural and common to use arrays of base class pointers, right? If not, can you clarify that?

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >It made it sound (at least to me) that you were saying that
    >using arrays of pointers to base and taking advantage of polymorphism in that way would raise red flags.
    Yes, that's what I meant.

    >But you meant that using arrays of the base class objects themselves would raise red flags, right?
    This is a rather subtle point. An array of base class objects is legal and fine provided you really want an array of base class objects. If you want an array of derived class objects but you want to access those objects through an array of base class pointers, you'll likely get burned.

    The concept works syntactically, but logically it's problematic. Remember that array subscripting works as a pointer offset from the base address. What happens if the derived class object is larger than the base class object? The pointer offset will be wrong because pointer arithmetic doesn't recognize polymorphism. In other words, subscripting comes down to *( pointer + ( i * sizeof ( class ) ). If your array expects *( array + ( i * sizeof ( base ) ) and you actually give it *( array + ( i * sizeof ( derived ) ) where derived is of a different size than base (a likely occurance), bad things happen.

    Thus, arrays cannot be safely treated polymorphically in C++.
    My best code is written with the delete key.

  11. #11
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Array of base class objects:
    Base array[10];

    Array of base class pointers:
    Base* array[10];


    The first raises red flags. The second is common and valid.

    Of course I am assuming these will be used with derived classes. I think we both understand this, but when we say "array of base class pointers" or "array of pointers to base", I am thinking of the second example above, which is fine (in my opinion). However, it seems like you are either referring to the first example, which we agree can be very dangerous, or you also think the second example is bad. If it's the latter, then why is the second example bad?

  12. #12
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Okay, I'm confused.

    If I had an array of Base object pointers.

    Code:
      Base * objs[ 2 ] ;
    And I created two derived objects, and stored their addresses in the Base array.

    Code:
      Derived d1, d2 ;  
      objs[ 0 ] = &d1 ;
      objs[ 1 ] = &d2 ;
    Are you saying that the following two printfs() may not print the same address?

    Code:
      printf( "%d\n", &d2 ) ;
      printf( "%d\n", *(objs + 1) ) ;
    Last edited by Dante Shamest; 03-11-2004 at 06:56 PM.

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    I think you've confused my point. I'm talking about an array of derived objects accessed by a base pointer as in a dynamic array:
    Code:
    base *array = new derived[n];
    At this point the compiler sees base pointers, not derived pointers. All pointer arithmetic will use the size of a base in the offset calculations. This is not what you want because you are really working with derived objects, which will likely be larger than base objects.

    >it seems like you are either referring to the first example, which we agree can be very dangerous
    I'm not referring to the first example because the first example is illegal. It's danger is irrelevant because abstract classes cannot be instantiated.

    >or you also think the second example is bad
    I appologize for the confusion. See below.

    >Are you saying that the following two printfs() may not print the same address?
    No, that will work because you're treating the elements of the array polymorphically, not the array itself. I concede that this is a subtle point that may not be relevant to the original question. Try this instead:
    Code:
    int main()
    {
      derived objs[2];
      base *p = objs;
    
      printf( "%d\n", objs ) ;
      printf( "%d\n", p ) ;
      printf( "%d\n", objs + 1 ) ;
      printf( "%d\n", p + 1 ) ;
    }
    My point was that when the static type of an array is of base but the dynamic type is of derived, pointer arithmetic will have incorrect results when the size of derived is different from the size of base. And I will remember to include example code in my first reply in the future so as to avoid confusion about the point I'm trying to make.
    My best code is written with the delete key.

  14. #14
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    Ah, I see what you mean Prelude. Its dangerous to use a Base pointer, pointing to a Derived array, and perform pointer arithmetic using the Base pointer.

  15. #15
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    As usual, the answer to my question is c) none of the above. I didn't think of that interpretation. I just hope its clear to anyone else reading this thread.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. virtual base class constructor
    By George2 in forum Windows Programming
    Replies: 1
    Last Post: 03-24-2008, 12:43 AM
  2. Can't Access the private member from base class
    By planet_abhi in forum C# Programming
    Replies: 3
    Last Post: 01-09-2006, 04:30 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Replies: 4
    Last Post: 12-29-2002, 12:29 AM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM