1

I have a abstract class named Base from which I derived a class(Derived) as follows:

#include <iostream>
#include <string>
#include <memory>

class Base
{
public:
    virtual void printClass()const = 0;
    virtual ~Base(){}
};

class Derived: public Base
{
private:
    int m_var1;
    std::string m_var2;
public:
    Derived() = default;
    Derived(const int& v1, const std::string& v2)
        :m_var1(v1), m_var2(v2)
        {        }

    void printClass()const override
    {
        std::cout << "Derived Class with\t";
        std::cout << m_var1 << " " << m_var2 << std::endl;
    }
    ~Derived(){ std::cout << "Derived destroyed" << std::endl; }
};

Now in the main() to make use of polymorphisum I could declare as follows:

int main()
{
    std::shared_ptr<Base> Obj[3];
    Obj[0] = std::make_shared<Derived>(1,"One");
    Obj[1] = std::make_shared<Derived>(2,"Two");
    Obj[2] = std::make_shared<Derived>(3,"Three");

    for(const auto& it: Obj)
        it->printClass();
    return 0;
}

However, I am currently trying to learn more about the std::shared_ptr<>() and its custom deletion technics and I came across following statement.

std::shared_ptr<Base> Obj(new Derived[3], [](Derived* obj){ delete[] obj; });

and

std::shared_ptr<Base> Obj(new Derived[3] = { 
                                              {1,"One"}, 
                                              {2,"Two"}, 
                                              {3,"Three"} 
                                           }, 
                                           [](Derived* obj){ delete[] obj; });

My questions are:

  1. Why I can not initialize or pass values to the constructor of Derived class in following manner, even-though I have a costume defined constructor available for the derived class? or am I missing something?
  2. If so what would be the correct way of initializing and accessing such array of derived class elements?
3
  • What would you do with the resulting shared pointer? You couldn't access any but the first array element. Commented Apr 8, 2018 at 22:18
  • @KerrekSB: Yes, exactly that's what I experienced. I even tried to increment the pointer(like we do in normal array pointer case), but that did not work. Now the question is what happens exactly when I create an array like above? can I access those(i.e Derived[1] and Derived[2] ) ? Commented Apr 8, 2018 at 22:28
  • 1
    There's nothing special about the array. The entire problem comes from casting the Derived pointer to a Base pointer, which effectively throws away all information about the ambient array. Commented Apr 8, 2018 at 22:35

1 Answer 1

2

You can call the constructor like this:

std::shared_ptr<Base> Obj{
    new Derived[3]{ {1,"One"}, {2,"Two"}, {3,"Three"} },
    [](Derived* obj){ delete[] obj; }
};
Sign up to request clarification or add additional context in comments.

2 Comments

Yes that works. So here we can not do like STL containers like for example: std::map<int, std::string> mp = { {1,"One"}, {2,"Two"}, {3,"Three"} };. Could you also explain, why its like that? and also how can access each members in the array?
You can, but not when creating a temporary. See the syntax for copy-initialization.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.