Question

Perhaps I am worrying over nothing. I desire for data members to closely follow the RAII idiom. How can I initialise a protected pointer member in an abstract base class to null?

I know it should be null, but wouldn't it be nicer to ensure that is universally understood?

Putting initialization code outside of the initializer list has the potential to not be run. Thinking in terms of the assembly operations to allocate this pointer onto the stack, couldn't they be interrupted in much the same way (as the c'tor body) in multithreading environments or is stack expansion guaranteed to be atomic? If the destructor is guaranteed to run then might not the stack expansion have such a guarantee even if the processor doesn't perform it atomically?

How did such a simple question get so expansive? Thanks.

If I could avoid the std:: library that would be great, I am in a minimilist environment.

Was it helpful?

Solution

Perhaps you're over-thinking this. The following example has the base member intialized to null:

struct Base
{
    virtual ~Base() = 0; // or make something else pure; this is just an example

    Base() : p() { }           // p initialized to null
    Base(Foo * q) : p(q) { }   // another option

protected:
     Foo * p;
};

struct Derived : private Base
{
    // no extra work needed

    // maybe something like this...
    Derived(int a, bool c) : Base(new Foo(a * (c ? 2 : 3))) { }
};

The derived constructor calls the base constructor first thing, and that one in turn says that Base::p gets initialized to zero.

OTHER TIPS

very easily: the best way is by using smart pointers, really don't avoid the standard it generally does things better than your average implementation.

class base{
public:
    base() : a(new int(5)) {}
protected:
    std::unique_ptr<int> a;
    virtual ~base() {} 
};

class child : public base {
     child() : base() {}
     ~child() {} //a will automatically be deleted
};

Now in this case unless the pointer is used by the child (which is often not a great design) then it can be made private.

Another way would be to manually delete it in the base destructor

class base{
public:
    base() : a(new int(5)) { }    //base member init'd
protected:
    int* a;
    virtual ~base() { delete a;  } //base member destroyed
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top