开发者

Using pointer to base class as array parameter

开发者 https://www.devze.com 2022-12-18 16:57 出处:网络
I have 2 classes: class Base { public: virtual int Foo(int n); virtual void Goo() = 0; virtual ~Base() ; }; class Derived : public Base

I have 2 classes:

class Base
{
public:
     virtual int Foo(int n);
         virtual void Goo() = 0;
     virtual ~Base() ;
};


class Derived : public Base
{
public:
    int开发者_C百科 Add4Bytes;

        void Goo();
    int  Foo(int n);    
};

int Test(Base* b)
{
    for (int i=0;i<5;++i)
    {
        b->Foo(i);
        ++b;
    }
    return 0;
}

void Test2(Base arr[])
{
    for (int i=0;i<5;++i)
    {
        arr[i].Foo(i);
    }
}

void main
{

      Base* b = new Derived[5];
      Test(b);
}

So, when i'm calling Test, after the second loop there a memory viloation exception.

I have 2 questions:

  1. What's the difference between the function argument in Test and Test2 ? (Test2 doesn't compile after i turned Base into pure abstract class).

and the more important question

  1. How can i prevent that exception, and how can i pass an array of derived class to a function that suppose to get a base class array. (i can't tell in compile time which derived class i'm gonna pass the function)

p.s - please don't tell me to read Meyers book, that's the exact reason why i'm asking this question. :)

Thanks


There's no difference between the parameter types, array parameters are adjusted to pointers in function declarations.

While you can convert a pointer to Derived to a pointer to Base, you can't treat an array of Derived as an array of Base, they are not related types. This is because in an array of Derived, the Base class is a sub-object of Derived and not part of an array of Base. When you perform pointer arithmetic as though it were part of an array of Base you are getting undefined behaviour, you are likely to construct a Base pointer that doesn't point exactly at the start of a Base object.


Arrays don't deal well with polymorphic types as contents due to object slicing. An array element has a fixed size, and if your derived objects have a larger size than the base then the array of base objects can't actually hold the derived objects.

Even though the function parameter might be decaying into a pointer, the pointer arithmetic done on that pointer will be based on the element size of the array type.

To deal with arrays of polymorphic types, you'll need to add another level of indirection and deal with arrays (or some other container) of pointers to the objects.

Test2 doesn't compile after i turned Base into pure abstract class

You can't have arrays of abstract types because you can't have instances of abstract types (only pointers or references to them).


Your Test function steps through array of Base objects, i.e. the stride is sizeof( Base ), while it needs to be sizeof( Derived ). You probably want to declare it as:

int Test( const std::vector<Base*>& );


You can find additional information about arrays of base and derived classes in C++ FAQ Lite question 21.4: Is an array of Derived a kind-of array of Base?

0

精彩评论

暂无评论...
验证码 换一张
取 消