473,385 Members | 1,907 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Smart pointers and this

I'm using reference counted smart pointers in a small project and it's
a breeze, but I'm running into a problem which I don't know how to
approach.

Consider something like this:

class A {
public:
A() {}
void setObserver(counted_ptr<Bobserver) { _observer =
observer; }

private:
counted_ptr<B_observer;
};

class B {
public:
B() {
_a = counted_ptr<A>(new A);
_a->setObserver(counted_ptr<B>(this));
}

private:
counted_ptr<A_a;
};
>From what I can see, the problem is creating a smart pointer with an
already existing raw pointer. In this case, the problem is that when
A's destructor is called (while B is being destroyed), it will destroy
_observer, which having a ref count of 1, will delete the pointed
object (B), which is not a good thing.

The easiest alternative I thought for this case is using a reference
instead, but I'd like to know if there's some way to fix this problem
(having an extra reference to avoid deletion somehow, etc)

Thanks!

Sep 18 '07 #1
7 2116
si*********@gmail.com wrote:
I'm using reference counted smart pointers in a small project and it's
a breeze, but I'm running into a problem which I don't know how to
approach.

Consider something like this:

class A {
public:
A() {}
void setObserver(counted_ptr<Bobserver) { _observer =
observer; }

private:
counted_ptr<B_observer;
};

class B {
public:
B() {
_a = counted_ptr<A>(new A);
_a->setObserver(counted_ptr<B>(this));
}

private:
counted_ptr<A_a;
};
>>From what I can see, the problem is creating a smart pointer with an
already existing raw pointer. In this case, the problem is that when
A's destructor is called (while B is being destroyed), it will destroy
_observer, which having a ref count of 1, will delete the pointed
object (B), which is not a good thing.

The easiest alternative I thought for this case is using a reference
instead, but I'd like to know if there's some way to fix this problem
(having an extra reference to avoid deletion somehow, etc)
Your best bet is to use boost::shared_ptr and boost::weak_ptr. See
http://www.boost.org/libs/smart_ptr/smart_ptr.htm for more information.

Joe Gottman
Sep 18 '07 #2
si*********@gmail.com wrote:
I'm using reference counted smart pointers in a small project and it's
a breeze, but I'm running into a problem which I don't know how to
approach.

Consider something like this:

class A {
public:
A() {}
void setObserver(counted_ptr<Bobserver) { _observer =
observer; }

private:
counted_ptr<B_observer;
};

class B {
public:
B() {
_a = counted_ptr<A>(new A);
_a->setObserver(counted_ptr<B>(this));
}

private:
counted_ptr<A_a;
};
>>From what I can see, the problem is creating a smart pointer with an
already existing raw pointer. In this case, the problem is that when
A's destructor is called (while B is being destroyed), it will destroy
_observer, which having a ref count of 1, will delete the pointed
object (B), which is not a good thing.
A & B objects would never get deleted. You need to decide who owns who.
You then need a smart pointer type that does not assume ownership
(usually referred to as a weak pointer). Austria C++ uses Ptr and
PtrView (Ptr for ownership and PtrView as a weak pointer). Boost I
think uses shared_ptr and weak_ptr.
>
The easiest alternative I thought for this case is using a reference
instead, but I'd like to know if there's some way to fix this problem
(having an extra reference to avoid deletion somehow, etc)
This is a design issue. Cyclic graphs of smart pointers must be avoided
in your design, otherwise you will have issues.
Sep 18 '07 #3
Your best bet is to use boost::shared_ptr and boost::weak_ptr. Seehttp://www.boost.org/libs/smart_ptr/smart_ptr.htmfor more information.

Aha! seems that I'm not the first one having this problem.. Many
thanks, this looks interesting, although the FAQ at the end of this
page http://www.boost.org/libs/smart_ptr/weak_ptr.htm seems to say
that I can't use this as intended in the example snippet (inside a
ctor). Anyway I'll search for further info about these weak pointers.
Thanks for the hint.

Sep 18 '07 #4
On Sep 18, 4:53 pm, sip.addr...@gmail.com wrote:
Your best bet is to use boost::shared_ptr and boost::weak_ptr. Seehttp://www.boost.org/libs/smart_ptr/smart_ptr.htmformore information.

Aha! seems that I'm not the first one having this problem.. Many
thanks, this looks interesting, although the FAQ at the end of this
pagehttp://www.boost.org/libs/smart_ptr/weak_ptr.htmseems to say
that I can't use this as intended in the example snippet (inside a
ctor). Anyway I'll search for further info about these weak pointers.
Thanks for the hint.
boost:enable_shared_from_this

Sep 19 '07 #5
On Sep 19, 1:53 am, sip.addr...@gmail.com wrote:
Your best bet is to use boost::shared_ptr and boost::weak_ptr. Seehttp://www.boost.org/libs/smart_ptr/smart_ptr.htmformore information.

Aha! seems that I'm not the first one having this problem.. Many
thanks, this looks interesting, although the FAQ at the end of this
pagehttp://www.boost.org/libs/smart_ptr/weak_ptr.htmseems to say
that I can't use this as intended in the example snippet (inside a
ctor). Anyway I'll search for further info about these weak pointers.
Thanks for the hint.
I would also like to thank Gianni Mariani and Tim H for their helpful
replies. Unfortunately it seems that google news don't display them
for some reason (I only get to see 3 of the 5 messages in the thread!)

Regarding Gianni's last point:
This is a design issue. Cyclic graphs of smart pointers must be avoided
in your design, otherwise you will have issues.
The only thing I'm expecting to use is a simple observer facility. A
parent class creates a child class, and needs to get notified of some
events generated by this child class. So after instantiating the
child, I register the parent to listen for events. I think this is the
easiest way to achieve this. Are there better alternatives?

Thank you.

Sep 22 '07 #6
On Sep 19, 1:05 am, sip.addr...@gmail.com wrote:
I'm using reference counted smart pointers in a small project and it's
a breeze, but I'm running into a problem which I don't know how to
approach.
Consider something like this:
class A {
public:
A() {}
void setObserver(counted_ptr<Bobserver) { _observer =
observer; }
private:
counted_ptr<B_observer;
};
class B {
public:
B() {
_a = counted_ptr<A>(new A);
_a->setObserver(counted_ptr<B>(this));
}
private:
counted_ptr<A_a;
};
From what I can see, the problem is creating a smart pointer with an
already existing raw pointer. In this case, the problem is that when
A's destructor is called (while B is being destroyed), it will destroy
_observer, which having a ref count of 1, will delete the pointed
object (B), which is not a good thing.
Presumably, your counted_ptr is similar to boost::shared_ptr.
If so, you're misusing it. It represents *shared* ownership
(which is actually pretty rare), and the observer pattern
doesn't involve ownership. It's pure navigation, which means
that you should probably be using raw pointers (although there
are special cases when some other type of smart pointer might be
appropriate).
The easiest alternative I thought for this case is using a
reference instead, but I'd like to know if there's some way to
fix this problem (having an extra reference to avoid deletion
somehow, etc)
Just use a raw pointer. In general, when pointers are used for
navigation, rather than for ownership, raw pointers are the most
appropriate solution.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 23 '07 #7

sip.addr...@gmail.com wrote:

Regarding Gianni's last point:
This is a design issue. Cyclic graphs of smart pointers must be avoided
in your design, otherwise you will have issues.

The only thing I'm expecting to use is a simple observer facility. A
parent class creates a child class, and needs to get notified of some
events generated by this child class. So after instantiating the
child, I register the parent to listen for events. I think this is the
easiest way to achieve this. Are there better alternatives?
While it can be noted that cyclic graphs must be avoided, weak
pointers can break these cycles. I've had problems very
recently where I attempted to write a generic
subscriber/observer which, if you inherited from it automatically
subscribed during construction, and unsubscribed at destruction.

The problem was that one could not use normal pointers, as
the subject (publisher) then had to notify its observers when
it got deleted so the observers who kept a reference did not call
unsubscribe on the invalid reference. To take it further, one part
of the application was decoupled from another by observing the
other and visa versa, therefore one had not choice but either
explicitly unsubscribe, or face UB. The solution was simply to
use weak pointers conservatively. One could probably have used
policies, making weak_ptr the default policy, and allowing the
user to define a reference or pointer policy if he chooses.

Regards,

Werner

Sep 23 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: lokb | last post by:
Hi, I have a structure which and defined a smart pointer to the structure. /* Structure of Begin Document Index Record */ typedef struct BDI_Struct{ unsigned char rname; unsigned short int...
9
by: christopher diggins | last post by:
I would like to survey how widespread the usage of smart pointers in C++ code is today. Any anecdotal experience about the frequency of usage of smart pointer for dynamic allocation in your own...
27
by: Susan Baker | last post by:
Hi, I'm just reading about smart pointers.. I have some existing C code that I would like to provide wrapper classes for. Specifically, I would like to provide wrappers for two stucts defined...
8
by: Axter | last post by:
I normally use a program call Doxygen to document my source code.(http://www.stack.nl/~dimitri/doxygen) This method works great for small and medium size projects, and you can get good...
92
by: Jim Langston | last post by:
Someone made the statement in a newsgroup that most C++ programmers use smart pointers. His actual phrase was "most of us" but I really don't think that most C++ programmers use smart pointers,...
33
by: Ney André de Mello Zunino | last post by:
Hello. I have written a simple reference-counting smart pointer class template called RefCountPtr<T>. It works in conjunction with another class, ReferenceCountable, which is responsible for the...
4
by: Deep | last post by:
I'm in doubt about what is smart pointer. so, please give me simple description about smart pointer and an example of that. I'm just novice in c++. regards, John.
54
by: Boris | last post by:
I had a 3 hours meeting today with some fellow programmers that are partly not convinced about using smart pointers in C++. Their main concern is a possible performance impact. I've been explaining...
50
by: Juha Nieminen | last post by:
I asked a long time ago in this group how to make a smart pointer which works with incomplete types. I got this answer (only relevant parts included): ...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.