1

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.

John
  • 6,433
  • 7
  • 47
  • 82

2 Answers2

3

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
};
111111
  • 15,686
  • 6
  • 47
  • 62
  • Any other ideas? I don't have std:: library available to me. I had no idea I could have a c'tor in my abstract base class. – John Feb 26 '12 at 23:26
  • Yes the lower idea, abstract classes can (and should have) a constructor and destructor. that will solve your problem. Out of interest why don't you have the std lib, what target/compiler? – 111111 Feb 26 '12 at 23:29
  • @John: Just curious, are you writing code for embedded system? Why is the environment minimal? – Jesse Good Feb 26 '12 at 23:30
  • 1
    @john you have access to the std lib use it: http://developer.bada.com/help/index.jsp?topic=/com.osp.cppapireference.help/group__Cplusplus.html – 111111 Feb 26 '12 at 23:35
  • That said you probably don't have unique ptr, you can easily write your own or use std::auto_ptr with caution. (still better than self management). – 111111 Feb 26 '12 at 23:37
  • @111111 that lib is restricted to 2.0 unfortunately only limited availability in last coupla months. I should have added I am on 1.2. Also no exceptions, so std:: is discouraged. – John Feb 27 '12 at 00:01
  • @John: Exceptions aren't the result of any library; exceptions are fundamental to C++. If you don't want them, you better guarantee that you can make all your constructors non-throwing. – Kerrek SB Feb 27 '12 at 00:09
  • @John at that point, I would say, there is no point writing C++ without major chunks of the language ill just write C. – 111111 Feb 27 '12 at 15:07
  • @KerrekSB: That is exactly the ideology behind Samsung's choice to disregard the exception mechanism- to encourage exception handling locally. I've bought this justification and into this approach to OOB. I like embedded systems, I like C, it's just not powerful enough. – John Feb 28 '12 at 00:38
3

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.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Just been reading too much `if (p) delete p;` wizard generated code perhaps? – John Feb 26 '12 at 23:30
  • @John: I added a bit more non-trivial example matter. The `delete` should go in the base destructor, like `Base::~Base() { delete p; }`. (Indeed, don't ever say `if`.) – Kerrek SB Feb 26 '12 at 23:32
  • @John: I think "cult generated" would be more apt :-) – Kerrek SB Feb 26 '12 at 23:33