Board index » cppbuilder » Passing a "this" reference on a form

Passing a "this" reference on a form


2007-11-02 01:00:23 AM
cppbuilder89
I have two data members of a form TDigraph
hyperMap Hypernyms;
Edges Digraph;
of the following types
typedef std::map<WordSense,int>hyperMap;
typedef std::list<EdgeList>Edges;
where a WordSense is a struct and an EdgeList is a class.
I declare another form in TDigraph with a reference
TSearchReplaceForm* d = new TSearchReplaceForm(this);
d->Digraph = this;
In a function in d, I call Digraph->CollectEdges where I fill Hypernyms
and Digraph. When I finish with d, I delete it and continue with other
function calls in TDigraph that attempt to make use of Hypernyms and
Digraph. But, Hypernyms is empty and Digraph is fine. Can anyone see
something that I'm missing.
TIA,
Ken
--
Ken Litkowski TEL.: 301-482-0237
CL Research EMAIL: XXXX@XXXXX.COM
9208 Gue Road
Damascus, MD 20872-1025 USA Home Page: www.clres.com
 
 

Re:Passing a "this" reference on a form

Ken Litkowski < XXXX@XXXXX.COM >writes:
Quote
I declare another form in TDigraph with a reference

TSearchReplaceForm* d = new TSearchReplaceForm(this);
d->Digraph = this;

In a function in d, I call Digraph->CollectEdges where I fill
Hypernyms and Digraph. When I finish with d, I delete it and continue
with other function calls in TDigraph that attempt to make use of
Hypernyms and Digraph. But, Hypernyms is empty and Digraph is fine.
Can anyone see something that I'm missing.
It's hard to start to answer anything since so much is omitted. For
example, how does TSearchReplaceForm store Digraph when you assign it?
What does the operator= look like?
Are you sure that it's holding the proper address when you call
CollectEdges? Is it invoked on the right object? Are you sure that
your collections are populated at all? Are the the ones you expect,
or perhaps a copy? Are you using an object after deleting it?
On another line of inquery, does any of this problem have *anything*
to do with the VCL code? If not, try to minimize your example to not
use VCL code, and to be entirely contained in a single C++ source
file, which is perhaps 50 lines at most. I'd be happy to take a look
at it if you posted such a file, but I cannot help without code that
actually demonstrates the problem, and I don't have the ability to
test anything using the VCL (since my platform is linux.)
It's probably something small, ultimately, but with so much to be
assumed, it's impossible to say what it is.
--
Chris (TeamB);
 

Re:Passing a "this" reference on a form

Something bizarre is going on, which I don't understand, but the
"problem" seems to have been resolved. You are correct that this is not
intrinsically VCL. I happened to be working with forms, which is why I
posted here (not thinking).
The answer to the first question is that in TSearchReplaceForm, Digraph
was a pointer, so the question of assignment seems irrelevant. When I
call CollectEdges, the pointer was to the same as "this", so it would
have seemed that I was at the right place. I was "sure" that my
collections were being populated. For Hypernyms, the code was as follows:
WordSense hypernym(entryPair->Word,entryPair->Sense);
if((h=Hypernyms.find(hypernym))!=Hypernyms.end())
(*h).second++;
else
Hypernyms[hypernym] = 1;
I added a line after this code to determine the size of Hypernyms after
each time this code was invoked, thusly:
int hsize = Hypernyms.size();
It was only after I added this that Hypernyms seemed to be accessible
after I had finished CollectEdges.
This doesn't make sense, but I'll live with it for the moment.
Thanks,
Ken
Chris Uzdavinis (TeamB) wrote:
Quote
Ken Litkowski < XXXX@XXXXX.COM >writes:

>I declare another form in TDigraph with a reference
>
>TSearchReplaceForm* d = new TSearchReplaceForm(this);
>d->Digraph = this;
>
>In a function in d, I call Digraph->CollectEdges where I fill
>Hypernyms and Digraph. When I finish with d, I delete it and continue
>with other function calls in TDigraph that attempt to make use of
>Hypernyms and Digraph. But, Hypernyms is empty and Digraph is fine.
>Can anyone see something that I'm missing.

It's hard to start to answer anything since so much is omitted. For
example, how does TSearchReplaceForm store Digraph when you assign it?
What does the operator= look like?
Are you sure that it's holding the proper address when you call
CollectEdges? Is it invoked on the right object? Are you sure that
your collections are populated at all? Are the the ones you expect,
or perhaps a copy? Are you using an object after deleting it?

On another line of inquery, does any of this problem have *anything*
to do with the VCL code? If not, try to minimize your example to not
use VCL code, and to be entirely contained in a single C++ source
file, which is perhaps 50 lines at most. I'd be happy to take a look
at it if you posted such a file, but I cannot help without code that
actually demonstrates the problem, and I don't have the ability to
test anything using the VCL (since my platform is linux.)

It's probably something small, ultimately, but with so much to be
assumed, it's impossible to say what it is.

--
Ken Litkowski TEL.: 301-482-0237
CL Research EMAIL: XXXX@XXXXX.COM
9208 Gue Road
Damascus, MD 20872-1025 USA Home Page: www.clres.com
 

{smallsort}

Re:Passing a "this" reference on a form

Ken Litkowski < XXXX@XXXXX.COM >writes:
Quote
The answer to the first question is that in TSearchReplaceForm,
Digraph was a pointer, so the question of assignment seems irrelevant.
The reason I asked was more about the potential for operator= to be
user-defined and somehow changing or somehow not assigning the right
value. In the end, a malfunction assignment operator might not assign
what is desired (or assumed), and then we end up with different values
than we thought. It was just a guess.
...
Quote
if((h=Hypernyms.find(hypernym))!=Hypernyms.end())
(*h).second++;
else
Hypernyms[hypernym] = 1;
Different topic, but I couldn't help but comment on this code. It's
more obscure than necessary and inefficient. For each insertion there
are two lookups in the map (the first is the find() call that failed,
and the second is done by operator[] to find the location where the
insertion should occur.)
Fortunately, there is a trivially simple replacement that addresses
these issues: (more readable, simpler, and more efficient). The
whole if can be replaced by this:
++Hypernyms[hypernym];
(If the item is not there, it will initialize the value to zero
automatically, so unconditionally incrementing it is correct whether
the item was there or not.)
HTH.
--
Chris (TeamB);
 

Re:Passing a "this" reference on a form

Thanks, Chris. I like your suggested code. I have used my method
frequently and this will certainly improve this kind of operation.
Chris Uzdavinis (TeamB) wrote:
Quote
>if((h=Hypernyms.find(hypernym))!=Hypernyms.end())
>(*h).second++;
>else
>Hypernyms[hypernym] = 1;

Different topic, but I couldn't help but comment on this code. It's
more obscure than necessary and inefficient. For each insertion there
are two lookups in the map (the first is the find() call that failed,
and the second is done by operator[] to find the location where the
insertion should occur.)

Fortunately, there is a trivially simple replacement that addresses
these issues: (more readable, simpler, and more efficient). The
whole if can be replaced by this:

++Hypernyms[hypernym];

(If the item is not there, it will initialize the value to zero
automatically, so unconditionally incrementing it is correct whether
the item was there or not.)

HTH.

--
Ken Litkowski TEL.: 301-482-0237
CL Research EMAIL: XXXX@XXXXX.COM
9208 Gue Road
Damascus, MD 20872-1025 USA Home Page: www.clres.com
 

Re:Passing a "this" reference on a form

Ken Litkowski < XXXX@XXXXX.COM >writes:
Quote
Thanks, Chris. I like your suggested code. I have used my method
frequently and this will certainly improve this kind of operation.
Sometimes you do want something like your method, especially when the
default constructed value is expensive to calculate, or when you want
to create the object using a different constructor.
Then, a minor tweak to your algorithm will suffice: instead of using
find(), use lower_bound(). That returns an iterator to either the
thing you wanted, or the place where it should go.
So then you'd do something like this:
h = Hypernyms.lower_bound(hypernym);
if (h == Hypernyms.end() || (*h != hypernym))
{
// note that it uses "h" as a hint to where to insert the object.
// create obj however you want, just that it's the right type.
Hypernyms.insert(h, std::make_pair(hypernym, ObjectToInsert(...) ));
}
// now use h however you would use it, it refers to the right
// element in the map.
It may still end up making a copy of your object, but it does avoid
duplicate lookups in the map.
--
Chris (TeamB);