|
The class CFoo is a COM interface. It inherits multiply from, among other things, IDropSource and IDropTarget . In fact this is the reason I need to specialize the asignment operator for CComPtr<CFoo> . If I don't, then the compiler signals ambiguous conversions between CFoo* and IUnknown* because both IDropSource and IDropTarget derive from IUnknown .
Unfortunately, the specialized copy asignment operator breaks in VS 2003 but not in VS 2002.
|
|
|
|
|
Could you show the lines that give the ambiguous conversion error?
Thank You
Bo Hunter
|
|
|
|
|
Hi,
warning: this is sort of a newbie question!!!
I've got a list of pointers in a class which I often need to clear, I've tried the clear and remove methods but these only clear the entries from the list and dont actually delete the objects that the pointers point to. The way that I'm currently deleting these objects is by iterating through the list assigning the iterator to a local variable which is of the same type of the list variables. I then remove the iterator from the list and then delete the local variable ( delete ( *it ) ; doesnt work hence local variable). I then set the iterator to the beginning of the list and start the process all over again (assuming I havent reached the end of the list).
Is this the correct way of doing this? (it just seems very long winded and overly complex for something which must be common in most programs).
many thanks,
|
|
|
|
|
delete( *it ) should work, but you should probably do it in two stages: first delete the objects pointed to, then delete the list elements (the pointers themselves). My RemoveAll would probably look something like:
for ( list<int*>::iterator it = l.begin();
it < l.end();
++it )
{
delete( *it );
}
l.erase( l.begin(), l.end() ); where l is a list<int*>
[EDIT] To make it clear, I think the problem you're having is that you're deleting the current element, pointed to by this iterator, before moving to the next element, so the iterator can't get the next element. You could handle this in the classic linked-list fashion, by retrieving the next value of the iterator before deleting this one. [/EDIT]
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
cheers,
I'll give your code example a try tonight (knew there had to be an easier way ).
|
|
|
|
|
|
|
I've used this approach in the past,
struct DeleteObjectHelper
{
template< typename T>
void operator ()( const T* p ) const
{
delete p ;
}
template< typename K, typename T>
void operator ()( const std::pair< K, T>& p ) const
{
delete p.second ;
}
} ;
template <class C> EmptyContainer ( C& c )
{
std::for_each ( c.begin (), c.end (), DeleteObjectHelper ) ;
c.clear () ;
}
then it's used thus,
std::list<MyClass *> MyList ;
EmptyContainer ( MyList ) ;
std::map< std::string, MyClass * > MyMap ;
EmptyContainer ( MyMap ) ;
Paul
|
|
|
|
|
Not surprisingly, I suggest my little functor[^]
for_each(myList.begin(), myList.end(), free_ptr<MyClass>());
myList.clear();
|
|
|
|
|
I am confused and why I can not store information in an object. If I want to save this information what I have to do?
#include <list> std::list<rect> MyList;
RECT rc = {0,0,0,0};
MyList.push_back(rc);
std::list<rect>::iterator it = MyList.begin();
RECT& RectOne = (RECT) *it;
RectOne.left = -1;
RECT& RectTwo = (RECT) *it;
int left = RectTwo.left;
RectOne is reference to first element of the RECT container. I changed the value of the first element of the container, and look the value in RectTwo, but it didn’t change the value. Real confused.
Agha Khan
|
|
|
|
|
What appears to be happening is that due to the cast
RECT& RectOne = (RECT) *it; the compiler is generating a temporary object which is a copy of the object referred to by the return value of *it , then binding the reference RectOne to that temporary RECT object. Similarly, RectTwo is bound to a different temporary object.
The answer is simple: remove the casts. The compiler no longer generates temporaries, and both references are bound to the original object.
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Hi Agha,
Mike is absolutely right and I can tell you why, you are doing the wrong cast. You have a reference to a RECT and you are casting to a RECT.
This is what you should do, if you want to keep the cast
RECT& RectOne = (RECT<big><big>&</big></big>) *it;<br />
RectOne.left = -1;<br />
<br />
RECT& RectTwo = (RECT<big><big>&</big></big>) *it;<br />
int left = RectTwo.left;
Regards,
Fabian
|
|
|
|
|
Hi!,
I am developing a container for embedding Miscosoft Word documents.
I am using CoCreateInstance()to create object,
after creation I set the clientsite and with the help of IPersistInterface::Load I load the storage, at this moment a temporary file having extension .doc is created in the Temp folder.
I want to avoid the creation of the temporary .doc file in the Temp folder.
and I also want to know the reason as to why the temporary .doc file is created.
Thanks
Anshuman
|
|
|
|
|
Hi all
In my COM server i had an events what pass iterface as parameter
[...]
dispinterface _IMyObjectEvents{
methods:
[..]Event1([in]IMyInterface* pIface);
};
For this event ATL master generate code like this
class CProxy_IMyEvents<...>{
...
HRESULT Fire_Event1(IMyInterface* pIface)
{
for(...)//looking for all connected clients
{
...
CComVariant avarParams[1];
avarParams = pIface;//Invoke AddRef() for pIface
...
pConnection->Invoke(...);//Invoke this event for client
}//Invoke Release() for pIface by CComVariant destructor
}
So far as i know client should release all methods param (marked as [in])by oneself.
But in this code interface released by server.
Please clear up this subject for mee.
Thanks
|
|
|
|
|
In this particular case, the server (which is firing the event), is acting as a client to the event subscriber. A client is a caller, a server is a callee.
Clear?
Steve S
|
|
|
|
|
|
Hello there,
is it possible to instantiate a std::vector with an incomplete type? E.g.
--Header--
struct field_t;
class all_t
{
...
private:
std::vector<field_t> m_fields;
};
--Implementation--
struct field_t
{
long val1;
int val2;
};
all_t::all_t()
{
...
m_fields.resize(10);
...
}
--End--
What size is assumed by the vector when resize(10) is called? It seems to work with VC7.1 but is it portable or will it overwrite the heap sometimes later?
Regards
Josef
|
|
|
|
|
Josef Schroettle wrote:
is it possible to instantiate a std::vector with an incomplete type? E.g.
Oddly, enough, yes. As long as field_t is known at the time of instantiating variables of type all_t. It seems that any type which embeds a template instantiation doesn't really get instantiated until it's used to declare a value variable (i.e., not a pointer or reference). To be honest, I'm not sure if this is stipulated by the C++ standard or if this is a Microsoft extension.
Josef Schroettle wrote:
or will it overwrite the heap sometimes later?
I doubt it. MSVC doesn't allow you to instantiate all_t unless field_t is known at the point of instantiation. Since field_t is known, then also its size is known, and therefore the heap will be just fine.
If you do find whether this is standard C++ or not, please let me know.
--
Din mamma.
|
|
|
|
|
<small><b>Jörgen Sigvardsson wrote:</b></small>
<i>I doubt it. MSVC doesn't allow you to instantiate all_t unless field_t is known at the point of instantiation. Since field_t is known, then also its size is known, and therefore the heap will be just fine</i>
The question is there, that clients which just include the header file don't know the size of 'T'. But I assume that the vector<T> has always the same size and sizeof(T) is just needed when vector<t> gets memory for a chunk of T's. But in my opinion this is highly depending on the STL implementation, one could e.g. cache the sizeof(T) in a local variable of vector<> which would then be not the real size which is only known to the implementation file.
I'll try asking Scott Meyers which wrote the excellent book 'Effective STL'.
Josef
|
|
|
|
|
Josef Schroettle wrote:
that clients which just include the header file don't know the size of 'T'.
it doesn't matter, because the compiler will not try to calculate the sizes of container<T> until it really has to. Like in a .cpp file. And when that happens, the compiler will remind you that T is unknown if the declaration of T is not visible in the scope you're instantiating container<T>.
--
Din mamma.
|
|
|
|
|
Hello Jörgen,
Scott Meyers answered very fast and I include his reponse below:
-- Scott Meyers wrote ---
Not in portable code. Section 17.4.3.6 of the Standard states that using an incomplete type to instantiate a library component (such as vector) yields undefined behavior. On this topic, I encourage you to read
http://www.cuj.com/documents/s=7986/cujcexp2002austern/
-- End Scott Meyers ---
Sometimes it's good to get an authoritative answer from an expert...
Josef
|
|
|
|
|
Josef Schroettle wrote:
On this topic, I encourage you to read
http://www.cuj.com/documents/s=7986/cujcexp2002austern/
Clickety[^]
|
|
|
|
|
Hello All,
I have a window that runs in a seperate thread, so I have been making a modal dialog box. It only has one item in it, a static control with a picture. I need to make it so you can size down the dialog box and have scroll bars appear. I have done some work where I use scroll bars with a regular CWindowImpl<>, but I don't know how to make that go modal. The easiest way seems to have scroll bars in my dialog box, and it seems that would be an easy thing to do without manually handling all the scrolling logic and moving things around, but heck if I can figure out how to do any of it.
Also, how can I limit the resizing, like not letting the client area go larger than my picture? It would be REALLY cool to have the maximize button size the client area to the picture.
All Help is Greatly Appreciated
-- Rick
|
|
|
|
|
Hello.
I've just written a relatively simple COM application : an ATL COM Server (EXE) providing one COM object. I choosed EXE because I want an existing application (a Win32 server) to have a COM entry point.
First test :
I make a .VBS file that simply instantiate the component and call a method. It works very well. I can even add debug points on the running EXE server to trace the request.
Second test :
In fact, the client is more complicated, it's a DLL (it's an ISAPI extension, built with ATL Server Web Service wizard).
When the client make the SOAP request, the DLL correctly process it, forward it to the EXE COM Server. It looks like it's working correctly but I can't add debug points in my EXE server. After some investigation, it showed that the DLL was not forwarding the request to the running EXE server, it was instantiating another server process ! (as if it was an in process server).
I've got the idea it could be because the ISAPI DLL was running on an account (the IIS one) and the server on another (the current user, me). But after configuring the Web application so it uses my account I still have the same problem : in task manager I can see 2 server process with the same user name.
I'm not a COM Guru, so going short on ideas, anyone know what is happening?
|
|
|
|
|
What happens if you launch two copies of your script simultaneously?
If you still get two copies of your EXE, you probably registered your class objects as REGCLS_SINGLEUSE . This causes the class object's registration to be removed after the first class object was created. Unless you called CoRegisterClassObject again, the next time a call to CoGetClassFactory (which is called internally by CoCreateInstance ) occurs, the COM Service Control Manager starts up a new instance of your server.
If you want all clients to use the same server process, you should register your class objects as REGCLS_MULTIPLEUSE .
In an ATL server, you typically register your class objects by calling _Module.RegisterClassObjects in WinMain .
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|