ownership style question

T

tarmat

I've been using code such as the following, whereby I call the
constructor of a class with an object allocated on the heap. The
class is responsible for tidying up the memory.


class Base{};
class A : public Base {};
class B : public Base {};


class MyClass
{
private:

Base* m_pBase;

public:

MyClass(Base* pB):m_pBase(pB){}

~MyClass(){delete m_pBase;}
};


void SomeClass::SomeMethod()
{
//m_pMC is a member variable of type MyClass*

m_pMC = new MyClass(new A());

}

Intuitively, this seems like bad style. I feel that each object should
be responsible for the creation and deletion of objects it uses. Is
this intuition correct?

And, if so, how should I change the design? I can't do something like

void SomeClass::SomeMethod()
{
Base* pB = new A();

m_pMC = new MyClass(pB);

delete pB;
}

because m_pBase must be valid outside the scope of the class method.

How can I improve this design?

Thanks for any help and I hope this made sense!
 
I

Ivan Vecerina

|
| I've been using code such as the following, whereby I call the
| constructor of a class with an object allocated on the heap. The
| class is responsible for tidying up the memory.

The C++ standard library includes a smart pointer class that
was designed to express transfer of ownership: auto_ptr.

| class MyClass
| {
| private:
|
| Base* m_pBase;
|
| public:
|
| MyClass(Base* pB):m_pBase(pB){}
|
| ~MyClass(){delete m_pBase;}
| };
....
| How can I improve this design?

This could become:

class MyClass
{
private:
std::auto_ptr<Base> m_pBase;

//NOTE: for safety, you want to disable these 2 default ops here:
MyClass(MyClass const&); // not implemented
void operator=(MyClass const&); // not implemented

public:
MyClass(std::auto_ptr<Base> pB):m_pBase(pB){}
~MyClass() { /*auto-deleted*/ }
};


Note that there is a debate on whether std::auto_ptr parameters
should be passed by value (as above) or by reference.
The former is dangerous when a function has multiple parameters.
The latter is less explicit about the ownership transfer,
and can be cumbersome (requires the initialization of
an intermediate variable).


Regards,
Ivan
 
L

lilburne

Ivan said:
|
| I've been using code such as the following, whereby I call the
| constructor of a class with an object allocated on the heap. The
| class is responsible for tidying up the memory.

The C++ standard library includes a smart pointer class that
was designed to express transfer of ownership: auto_ptr.

You need to be careful with auto_ptr particularly with version 2
implementations which can leave you with dangling pointers. Version
three is supposed to reset the pointer to 0 after the transfer which
leads to better respect for the thing. You are probably better off with
something a little more robust like a shared_ptr.
 
I

Ivan Vecerina

|
| Ivan Vecerina wrote:
| > | > |
| > | I've been using code such as the following, whereby I call the
| > | constructor of a class with an object allocated on the heap. The
| > | class is responsible for tidying up the memory.
| >
| > The C++ standard library includes a smart pointer class that
| > was designed to express transfer of ownership: auto_ptr.
|
| You need to be careful with auto_ptr particularly with version 2
| implementations which can leave you with dangling pointers. Version
| three is supposed to reset the pointer to 0 after the transfer which
| leads to better respect for the thing. You are probably better off with
| something a little more robust like a shared_ptr.

But shared_ptr expresses shared ownership, where both the caller
and callee may keep using the owned object. It does not express
ownership transfer, and serves a very different purpose IMO.

Pre-standard versions of std::auto_ptr had problems, true.
But these are easy to avoid (assume that it is UB to use
an auto_ptr after it has been assigned to another instance).
And hopefully these outdated libraries are about to disappear
from developer's systems by now.

Yes, IIRC, MSVC6 still shipped with an awfully outdated
version of the standard library. But users who can't afford
updating their platform (nor purchasing the library update)
definitely should switch to the free STLport (www.stlport.org).
(at least if they care to use the standard C++ library at all).


Regards,
Ivan
 
L

lilburne

Ivan said:
|
| Ivan Vecerina wrote:
| >
| > The C++ standard library includes a smart pointer class that
| > was designed to express transfer of ownership: auto_ptr.
|
| You need to be careful with auto_ptr particularly with version 2
| implementations which can leave you with dangling pointers. Version
| three is supposed to reset the pointer to 0 after the transfer which
| leads to better respect for the thing. You are probably better off with
| something a little more robust like a shared_ptr.

But shared_ptr expresses shared ownership, where both the caller
and callee may keep using the owned object. It does not express
ownership transfer, and serves a very different purpose IMO.

I agree that the semantics of ownership transfer is a good
reason to use auto_ptr. One that resets the pointer to 0
after transfer is a far more solid implementation.
Pre-standard versions of std::auto_ptr had problems, true.
But these are easy to avoid (assume that it is UB to use
an auto_ptr after it has been assigned to another instance).
And hopefully these outdated libraries are about to disappear
from developer's systems by now.

Personally I don't like UB that can appear to work, because
it doesn't discourages misuse. I suspect that a few will get
a nasty surprise with V3 auto_ptr's.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top