473,386 Members | 1,864 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,386 software developers and data experts.

possibility to forbid use of "this"?

Dear Readers,

Is it possible to forbid conversion from this or use of this in general
except where it is explicitly wanted?

Reason:

I changed my program from using normal pointers to classes A, ...

typedef A * APtr;

to a shared pointer

typedef boost::shared_ptr<A> APtr;

Now, it crashes because of statements like this

// call
DoSomething(this);

.....
// implementation
void DoSomething(APtr a)
{
// do nothing with a
}

Obviously, "this" is converted to a shared ptr locally. Outside the function
DoSomething() the shared ptr is destroyed and hence it tries to delete the
class where "this" points, too. This is clearly not wanted.

Greetings,
Many thanks in advance

Ernst

Jul 22 '05 #1
14 2220
On Wed, 7 Jan 2004 14:53:45 +0100, "Ernst Murnleitner"
<mu******@awite.de> wrote:
Dear Readers,

Is it possible to forbid conversion from this or use of this in general
except where it is explicitly wanted?

Reason:

I changed my program from using normal pointers to classes A, ...

typedef A * APtr;

to a shared pointer

typedef boost::shared_ptr<A> APtr;

Now, it crashes because of statements like this

// call
DoSomething(this);

....
// implementation
void DoSomething(APtr a)
{
// do nothing with a
}
That shouldn't compile - the constructor of shared_ptr taking a T* is
explicit, so a pointer can't implicitly convert to a shared_ptr.
Obviously, "this" is converted to a shared ptr locally. Outside the function
DoSomething() the shared ptr is destroyed and hence it tries to delete the
class where "this" points, too. This is clearly not wanted.


You have a few choices, depending on what DoSomething does. If
DoSomething doesn't hold onto a reference to a, then you can change it
to:

void DoSomething(A& aref)
{
}

If it does hold onto a reference to a, but you know it will release
that reference before a is destroyed (which you probably can't
guarantee), then you could do:

struct null_deleter
{
void operator()(void const *) const
{
}
};

//...

DoSomething(APtr(this, null_deleter()));

The safe approach is to make a shared_ptr from the this pointer. This
is only possible if the A object was created as a shared_ptr in the
first place. Follow the instructions here:
http://www.boost.org/libs/smart_ptr/...html#from_this

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #2

"Ernst Murnleitner" <mu******@awite.de> wrote in message news:bt************@ID-130107.news.uni-berlin.de...
Obviously, "this" is converted to a shared ptr locally. Outside the function

DoSomething() the shared ptr is destroyed and hence it tries to delete the
class where "this" points, too. This is clearly not wanted.


shared_pointer(T*) isn't declared explicit? Seems like it ought to be.

Jul 22 '05 #3
> That shouldn't compile - the constructor of shared_ptr taking a T* is
explicit, so a pointer can't implicitly convert to a shared_ptr.


With gcc 2.95 it compiles:

// -------------------------------------
#include <iostream.h>

#include <stdlib.h>

#include <boost/shared_ptr.hpp>

class A;

typedef boost::shared_ptr<A> APtr;

class A {

public:

A(){};

virtual ~A(){};

virtual void f(){func(this); };

void func(APtr p) {cout << "func(APtr)" << std::endl;};

};

int main(int argc, char *argv[])

{

A a;

a.f();

return EXIT_SUCCESS;

}

// -------------------------------------

Jul 22 '05 #4

"Ron Natalie" <ro*@sensor.com> schrieb im Newsbeitrag
news:3f***********************@news.newshosting.co m...

"Ernst Murnleitner" <mu******@awite.de> wrote in message

news:bt************@ID-130107.news.uni-berlin.de...
Obviously, "this" is converted to a shared ptr locally. Outside the
function DoSomething() the shared ptr is destroyed and hence it tries to delete the class where "this" points, too. This is clearly not wanted.


shared_pointer(T*) isn't declared explicit? Seems like it ought to be.

At least with the old gcc 2.95 it need not! But I tried it with gcc 3.3 also
and at least there was the expected error.

(I still use the gcc 2.95 as the gcc 3.3 needs 20times longer for certain
source files).

Greetings
Ernst

Jul 22 '05 #5
On Wed, 7 Jan 2004 16:46:03 +0100, "Ernst Murnleitner"
<mu******@awite.de> wrote:
That shouldn't compile - the constructor of shared_ptr taking a T* is
explicit, so a pointer can't implicitly convert to a shared_ptr.


With gcc 2.95 it compiles:


That's a shame - you should upgrade. It suspect it fails with all of
the compilers I have (GCC 3.2, Comeau C++ 4.3, VC 7.1, VC 6?), since
it is non-standard.

With this change:
#include <iostream.h>
to
#include <iostream>
using namespace std;

Comeau gives this error:

"main.cpp", line 22: error: no suitable constructor exists to convert
from
"A *" to "boost::shared_ptr<A>"
virtual void f(){func(this); };

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #6

"Ernst Murnleitner" <mu******@awite.de> wrote in message
news:bt************@ID-130107.news.uni-berlin.de...

"Ron Natalie" <ro*@sensor.com> schrieb im Newsbeitrag
news:3f***********************@news.newshosting.co m...

"Ernst Murnleitner" <mu******@awite.de> wrote in message news:bt************@ID-130107.news.uni-berlin.de...
> Obviously, "this" is converted to a shared ptr locally. Outside the function DoSomething() the shared ptr is destroyed and hence it tries to delete the class where "this" points, too. This is clearly not wanted.


shared_pointer(T*) isn't declared explicit? Seems like it ought to be.

At least with the old gcc 2.95 it need not! But I tried it with gcc 3.3

also and at least there was the expected error.
The library now contains a enable_shared_from_this<>() function. You might
look up http://www.boost.org/libs/smart_ptr/sp_techniques.html

(I still use the gcc 2.95 as the gcc 3.3 needs 20times longer for certain
source files).


However, I´d recommend using gcc 3.3 and you probably might want to go
through your code for unnecessary compile time dependencies.

Regards
Chris
Jul 22 '05 #7
>
The library now contains a enable_shared_from_this<>() function. You might
look up http://www.boost.org/libs/smart_ptr/sp_techniques.html


I found this just before. Now I wonder if it is possible to use

shared_from_this();

during construction of an object. I want to use it in the base class and
only store it in a std::vector. It would be used only after complete
construction but is needed during construction, as childs are constructed
from withing the constructor of the parent. The childs eventually get a
pointer to the parent for later use.

Greetings

Ernst

Jul 22 '05 #8

"Ernst Murnleitner" <mu******@awite.de> wrote in message
news:bt************@ID-130107.news.uni-berlin.de...

The library now contains a enable_shared_from_this<>() function. You might look up http://www.boost.org/libs/smart_ptr/sp_techniques.html


I found this just before. Now I wonder if it is possible to use

shared_from_this();

during construction of an object. I want to use it in the base class and
only store it in a std::vector. It would be used only after complete
construction but is needed during construction, as childs are constructed
from withing the constructor of the parent. The childs eventually get a
pointer to the parent for later use.

Greetings

Ernst


Could you give an explicit code example of what you want to do, please
because creating childs within the ctor of a base sounds very much like
flawed design to me. But I would need to see some code. Anyway, if I
understand your description correctly then there should be no problem.
Still, you should test it as I´ve not used shared_from_this() so far.

Regards
Chris
Jul 22 '05 #9
"Ernst Murnleitner" <mu******@awite.de> wrote:
Dear Readers,

Is it possible to forbid conversion from this or use of this in general
except where it is explicitly wanted?

Reason:

I changed my program from using normal pointers to classes A, ...

typedef A * APtr;

to a shared pointer

typedef boost::shared_ptr<A> APtr;


I would call the above a bad idea. Not just because of the problem
cited, but because there is no way, in general to guarantee that all
APtr's in the original code actually point to things that must be
deleted at some point in the future. For example:

typedef A* APtr;

void foo( APtr a ) { }

int main() {
A myA;
foo( &myA );
}

is quite valid until you change the typedef...

Now if you can guarantee that all of the things held by an APtr have
actually been newed, then using a SmartPointer class that has some sort
of global way of knowing the number of references would be OK.

Of course, you still have the problem that some places in the code may
be using an A* rather than an APtr. :-(
Jul 22 '05 #10
> Could you give an explicit code example of what you want to do, please
because creating childs within the ctor of a base sounds very much like
flawed design to me.


A version, but without smartpointers, is at
http://control.awite.com/awitecontro...trol-api/html/

I am currently cleaning up the source, therefore my questions. I began 2
years ago and the ioverall design didn`t need changes. However, in the
beginning I didn't use more sophisticated programming technics like design
patterns, factory classes etc.

Greetings

Ernst

Jul 22 '05 #11
> Now if you can guarantee that all of the things held by an APtr have
actually been newed, then using a SmartPointer class that has some sort
of global way of knowing the number of references would be OK.
Yes, I only construct them on the heap. And if I only allow a factory to
create my Objects (e.g. as Mr. Carson suggested in another message thread),
I cannot accidentally define automatic variables.
Of course, you still have the problem that some places in the code may
be using an A* rather than an APtr. :-(


OK. Can I avoid this?

The factory only delivers sthared_ptr. The only possibility to use the
poiner would be to use the shared_ptr's get().

Greetings
Ernst

Jul 22 '05 #12
On Wed, 7 Jan 2004 18:24:54 +0100, "Ernst Murnleitner"
<mu******@awite.de> wrote:

The library now contains a enable_shared_from_this<>() function. You might
look up http://www.boost.org/libs/smart_ptr/sp_techniques.html
I found this just before. Now I wonder if it is possible to use

shared_from_this();

during construction of an object.


It isn't - the weak pointer is only initialized in the constructor of
the shared pointer, which is obviously run after the constructor of
your object.
I want to use it in the base class andonly store it in a std::vector. It would be used only after complete
construction but is needed during construction, as childs are constructed
from withing the constructor of the parent. The childs eventually get a
pointer to the parent for later use.


How are you creating your object? I suggest you use a factory, and
make the necessary extra calls after you've created the shared
pointer. e.g.

shared_ptr<YourType> make()
{
shared_ptr<YourType> ptr(new YourType);
//this was called from the YourType constructor before:
someFunc(ptr);
return ptr;
}

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #13
"Ernst Murnleitner" <mu******@awite.de> wrote:
Now if you can guarantee that all of the things held by an APtr have
actually been newed, then using a SmartPointer class that has some sort
of global way of knowing the number of references would be OK.


Yes, I only construct them on the heap. And if I only allow a factory to
create my Objects (e.g. as Mr. Carson suggested in another message thread),
I cannot accidentally define automatic variables.


class A {
protected:
A();
};

class B: public A {
public:
B();
}

void foo( A* a );

int main() {
B b;
foo( &b );
}

How are you going to stop A's from being created on the stack again?

Of course, you still have the problem that some places in the code may
be using an A* rather than an APtr. :-(


OK. Can I avoid this?

The factory only delivers sthared_ptr. The only possibility to use the
poiner would be to use the shared_ptr's get().


Fine, but then you must be changing the origional code rather than
simply changing a typedef from A* to shared_ptr<A>...
Jul 22 '05 #14
> >I found this just before. Now I wonder if it is possible to use

shared_from_this();

during construction of an object.
It isn't - the weak pointer is only initialized in the constructor of
the shared pointer, which is obviously run after the constructor of
your object.


I tried: it throws an exception (and is also documented this way).

Therefore I used in the constructor of the baseclass something like this:

std::vector<shared_ptr<Base> > Base::AllItemsVector;

Base::Base(...)
{
shared_ptr<Base> p (this);
Base::AllItemsVector.push_back(p);
....
shared_ptr<Base> pChild
(Factory::NewChild("newchildname",shared_from_this ()));
}

This way it seems to work. However, somewhere I read that shared_ptr cannot
be constructed in the constructor (but I cannot exactly remember). But this
seems to work.

Greetings

Ernst



I want to use it in the base class and
only store it in a std::vector. It would be used only after complete
construction but is needed during construction, as childs are constructed
from withing the constructor of the parent. The childs eventually get a
pointer to the parent for later use.


How are you creating your object? I suggest you use a factory, and
make the necessary extra calls after you've created the shared
pointer. e.g.

shared_ptr<YourType> make()
{
shared_ptr<YourType> ptr(new YourType);
//this was called from the YourType constructor before:
someFunc(ptr);
return ptr;
}

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

Jul 22 '05 #15

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

Similar topics

5
by: Michael Stevens | last post by:
Probably the wrong wording but since I'm not a scripter I won't claim to know what I'm talking about. I got this script from www.htmlgoodies.com <script language="JavaScript"> <!--...
3
by: maadhuu | last post by:
well,i am curious to know what would be the output of the following: delete this; basically , comment on this .
1
by: tnhoe | last post by:
Hi, <Form method='post' action="next.htm?btn="+"this.myform.myobj.value"> What is the correct syntax for above ? Regards Hoe
9
by: aden | last post by:
I have read the years-old threads on this topic, but I wanted to confirm what they suggest. . . Can the this pointer EVER point to a type different from the class that contains the member...
1
by: Shapper | last post by:
Hello, I am accessing a value in a XML value: news.Load(Server.MapPath("xml/ news.rss")) newslabel.Text = CType(news.SelectSingleNode("rss version=&quot;2.0 &quot;/channel/title").InnerText, String) ...
7
by: relient | last post by:
Question: Why can't you access a private inherited field from a base class in a derived class? I have a *theory* of how this works, of which, I'm not completely sure of but makes logical sense to...
8
by: solarin | last post by:
Hi all. I'm writting a logger class to write all the debug/info/warning/error messages in a file. Every time a class needs to send any message, should send a code (int) and a message (string)....
10
by: craig.keightley | last post by:
I am trying to get the next row within a loop for a script i am developing... I need to display a final table row within the table that i have displayed on the page, but i only want to show it...
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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.