1

From Effective Modern C++ by Scott Meyers, in reference to shared_ptrs to dynamic arrays (Item 19).

For one thing, std::shared_ptr offers no operator[], so indexing into the array requires awkward expressions based on pointer arithmetic. For another, std::shared_ptr supports derived-to-base pointer conversions that make sense for single objects, but that open holes in the type system when applied to arrays. (For this reason, the std::unique_ptr API prohibits such conversions.)

class A{
public:
    virtual ~A() = default;
    virtual void test(){ std::cout << "Ayyyyy" << std::endl;}

};

class B : public A {
public:
    virtual void test() override  {std::cout << "Beeeeeee" << std::endl;}

};

int main(){

    std::shared_ptr<A> p(new B[10], [](A* a){ delete [] a;});

    (p.get() + 2)->test();

}

Indexing can get awkward, but what type of "holes" are opened in the type system by using a shared pointer to an array with derived-to-base conversion? I'm struggling to think of an example. Whatever issues are faced with derived-to-base pointer conversions, I don't see how the use of array could have caused them. The example above works fine, so what level of complexity is needed before I start seeing issues with this?

I know it's better to just use std::array or std::vector anyway instead of pointing to a dynamic array, but I was just curious about this point.

AntiElephant
  • 1,227
  • 10
  • 18
  • 3
    Well, the pointer arithmetic is wrong: `p.get()` is not a pointer to an element of an array of `A`. – Kerrek SB Sep 21 '16 at 17:54
  • 1
    Also, your deleter has undefined behaviour. (That's arguably your deleter's fault and could be fixed, but it goes to show how complicated this gets.) – Kerrek SB Sep 21 '16 at 18:01
  • @KerrekSB Oh, is that to say `p.get()+1` would move the address the wrong "amount" (size of an A object instead of the size of a B object) and I probably haven't moved across one B object worth (that would be some sort of undefined behaviour surely)? I'm guessing that's then the problem faced with the deleter too. If that's true, I'm guessing in general derived-to-base conversions of arrays of derived-type must be a bad idea. – AntiElephant Sep 21 '16 at 18:06
  • 1
    Yes, those would be practical problems you'd face at implementation level, but it's all just undefined behaviour as far as the language rules are concerned. – Kerrek SB Sep 21 '16 at 18:08
  • @KerrekSB I see, thank you. – AntiElephant Sep 21 '16 at 18:12

0 Answers0