I'm using a library that, in order to construct some object that I use, expects a raw pointer to an object. I'm not sure what it will do with the pointer, to make my code as safe as possible, what should I pass to this function?
- Use a unique pointer - if they decide to delete the pointer, I will do a double-delete
- Keep track of a raw pointer - bad because I have to remember to write delete, but it could still be a double-delete
- Use auto duration and give them a pointer Give them a reference- their code will error if they call delete
- Use a shared pointer - same double-delete problem as unique pointer, but now my scope won't hurt their pointer
Based on my reading, option 3 seems like what I should do - they shouldn't be calling delete on the pointer, and this format enforces that. But what if I don't know whether they now or in the future will call delete on the reference I gave them? Use a shared pointer and say "not my fault about the double delete"?
#include <memory>
#include <iostream>
class ComplexObj {
  public:
    ComplexObj() : m_field(0) {}
    ComplexObj(int data) : m_field(data) {}
    void print() { std::cout << m_field << std::endl; }
  private:
    int m_field;
};
class BlackBox {
  public:
    BlackBox(ComplexObj* data) {
        m_field = *data;
        // Do other things I guess...
        delete data;
        std::cout << "Construction complete" << std::endl;
    }
    void print_data() { m_field.print(); }
  private:
    ComplexObj m_field;
};
int main(int argc, char* argv[]) {
    // Use a smart pointer
    std::unique_ptr<ComplexObj> my_ptr(new ComplexObj(1));
    BlackBox obj1 = BlackBox(my_ptr.get());
    obj1.print_data();
    my_ptr->print();  // Bad data, since BlackBox free'd
    // double delete when my_ptr goes out of scope
    // Manually manage the memory
    ComplexObj* manual = new ComplexObj(2);
    BlackBox obj2 = BlackBox(manual);
    obj2.print_data();
    manual->print();  // Bad data, since BlackBox free'd
    delete manual;    // Pair new and delete, but this is a double delete
    // Edit: use auto-duration and give them a pointer
    ComplexObj by_ref(3);
    BlackBox obj3 = BlackBox(&by_ref);  // they can't call delete on the pointer they have
    obj3.print_data();
    by_ref.print();
    // Use a shared pointer
    std::shared_ptr<ComplexObj> our_ptr(new ComplexObj(4));
    BlackBox obj4 = BlackBox(our_ptr.get());
    obj4.print_data();
    our_ptr->print();  // Bad data, they have free'd
    // double delete when our_ptr goes out of scope
    return 0;
}
Other questions I read related to this topic...
 
    