|
The :: syntax works for static variables, which are referenced at the class level. You need an instance of the OtherClass within your MyClass, so you can do this:
myOtherClass->ovPC->clear();
OR make your vector a static variable, which means you'll only have one, visible across all instances of the class.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Thanks for your reply.
Even though I have '#include "OtherClass.h"' present in the file where 'class MyClass' is defined, when in 'MyClass.cpp' (where all the actions are happening) I had the statement:
pvMyClass->pvOC->clear(); the compiler gave an error about 'pvOC' being undeclared (which made sense). That was when I did:
pvMyClass->OtherClass::pvOC->clear(); which took care of the "'pvOC' being undeclared" error, but didn't solve the other sytactical ones (which occurred due to the incorrectness of that statement and it being unacceptable to the compiler).
Subsequent experimental efforts gave encouragements, while others didn't, but none has produced a clean compile even when I did:
class MyClass
{
static vector<OtherClass> vOC;
};
=================
Then later:
vOC->pvOC->clear(); Take my word for it, I've done quite a bit of permutations on this effort and I think I might be beginning to suffer from tunnel vision.
William
Fortes in fide et opere!
|
|
|
|
|
Here's some alternatives that should work. I'll leave it up to you to decide which is the appropriate solution based on your design.
In this first one, I'm assuming that you want to clear the string vector instance in the instance of OtherClass that you're adding to pvMyClass . So, we create an instance of OtherClass , clear pvOC in the instance, then duplicate it into pvMyClass (remember, you can only access elements in STL containers by copying, so if you don't want to create a duplicate instance of OtherClass each time, use a vector<OtherClass*> instead).
class MyClass{
vector<OtherClass> *pvMyClass;
};
MyClass::MyClass(){
pvMyClass = new vector<OtherClass>;
}
class OtherClass{
vector<string> *pvOC;
};
OtherClass::OtherClass(){
pvOC = new vector<string>;
}
OtherClass oc = OtherClass();
oc.pvOC->clear();
pvMyClass->push_back(oc);
In this next one, I assume that all instances of OtherClass share that same pvOC , so I make it static.
class MyClass{
vector<OtherClass> *pvMyClass;
};
MyClass::MyClass(){
pvMyClass = new vector<OtherClass>;
}
class OtherClass{
static vector<string> *pvOC;
};
vector<string> *OtherClass::pvOC =
new vector<string>;
OtherClass::OtherClass(){
}
pvMyClass->push_back(OtherClass());
OtherClass::pvOC->clear();
- Mike
|
|
|
|
|
Thank you very much for your reply. I always gain something from your replies, and this time was no exception.
The first example was more the correct situation. I will use it as a stepping stone for advancing further into what I'm doing. (It's like having a dead car on your hand, then somebody came along and started it up for you. You still haven't gotten to where you're going, but the sound of the engine running again, does lift your spirit and give you hope.)
Thank you.
William
Fortes in fide et opere!
|
|
|
|
|
Hi William,
You may want to change the way that you are declaring your vectors. Under most cases, there is no benefit to declaring a pointer to a vector and then allocating the vector in the constructor. You just end up making the syntax different, and add the need to manually delete the vector in the destructor.
I would end up coding the classes something like this:
#include <vector>
using namespace std;
class OtherClass
{
vector<string> vOC;
public:
void AddString( const char* str )
{
vOC.push_back( str );
}
};
class MyClass
{
vector<OtherClass> vMyClass;
public:
void AddElements();
};
void MyClass::AddElements()
{
vMyClass.push_back( OtherClass() );
OtherClass& oc = vMyClass.back();
oc.AddString( "First" );
oc.AddString( "Second" );
oc.AddString( "Third" );
}
int main()
{
MyClass mine;
mine.AddElements();
return 0;
}
The cleanup of the vectors is handled automatically, with no need to call delete.
Best regards,
John
|
|
|
|
|
Thank you for your input.
The reason for the declaration of a pointer to a vector is to obtain persistency of the vector. IOW, I don't want the vector to be destroyed when processing leaves scope. I will be the one to destroy it when I'm about to exit the program.
William
Fortes in fide et opere!
|
|
|
|
|
When I look at a class like MyClass (in your original post), I would assume that the lifetime of the vector would be the same as the lifetime of the object that contains it. I would control when the vector gets destroyed by controlling the lifetime of the MyClass object, rather than getting a pointer to the vector out of the object.
Similarly, I would assume that the lifetime of the vector inside an OtherClass object should be the same as the object containing it.
For both of these objects, this seemed to be the case, as you were allocating the vector in the constructor of the object. You didn't show a destructor, so I couldn't tell whether you intended to keep the vector after destroying the object.
You might want to rethink this, as it seems that the ownership of the vectors really belong to the objects that contain the pointers.
I don't know what your intentions are, so I am not sure which way I would change this. ( Of course, you can just leave it the way it is... I am just giving my opinion )
If you intend MyClass to be a class that initializes a vector of OtherClass objects, but does not have anything to do with the vector afterwards, I would probably pass a reference to the vector to the constructor of the MyClass object. The ownership of the vector would then be outside of the MyClass object. The vector would persist because it would be declared at a higher level, and passed in to the MyClass object for initialization. The vector object could be declared as high level as you need it to persist, and could be passed by reference to the various routines that need it.
If you intend MyClass to be a class that is a vector of OtherClass objects, I would keep the actual vector inside the object (not a pointer), and make sure that the MyClass object persists (by either declaring it at a high enough level that it remains in scope, or by allocating a MyClass object with new). I personally would lean this way, as I could then add routines to manipulate the vector to the MyClass object.
Best regards,
John
|
|
|
|
|
I am using ofstream to write very large files, of size greater than MAX_LONG. It works fine except for one problem; when the file gets to big I cannot use tellp() to get the file position. It seems a little weird; tellp() returns an fpos<int> object which has a __int64 member in it (returned from get_fpos_t()) -- so I should be able to get the file size out of that member. But once the file size is over 2GB, that member is set to 0. What can I do? I am using Visual C++ 6.
READIN writin rhythmetic
|
|
|
|
|
What OS ? 2 gb is the file size limit for W98, which may be the issue.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Windows 2000 -- the file is getting written just fine, 7G output last time I ran the project; but while I'm writing I want to store file positions in an index file and cannot do that if I can't get a good file position. The workaround I found is to flush the file, then use _stati64 to get the file size -- I would prefer an STL solution if one exists.
READIN writin rhythmetic
|
|
|
|
|
Get it here! Enjoy the reading.
|
|
|
|
|
hi,all:
I have a ATL server ,and it support an interface with Connection Point.
I use MultiClient connect the Connection point.
I hope that,when data is received the connect point can fire all the
Connected Client. But I found that only the last client can receive the
fire. I mean that the number of connections in server is always 1.
Though the fact is MultiClient has Connected. It looks that ,all clients
were throw into a stack ,server process it one by one.
Why??
___________________________________________
HRESULT Fire_Draw(INT type, INT x, INT y)
{
CComVariant varResult;
T* pT = static_cast<t*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[3];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections;
nConnectionIndex++)
{
pT->Lock();
CComPtr<iunknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<idispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[2] = type;
pvars[1] = x;
pvars[0] = y;
DISPPARAMS disp = { pvars, NULL, 3, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
&disp, &varResult, NULL, NULL);
}
}
delete[] pvars;
return varResult.scode;
}
_____________________________________
m_vec.GetSize() is always 1.
I love fish,like i love C++.
|
|
|
|
|
Hi, all, i want to learn ATL, i could find books just like
<inside atl=""> <atl internal="">, but i heared that these books
are not suit to a beginner
Someone said <developers workshop="" to="" com="" and="" atl="" 3.0=""> is a
nice book for ATL beginner, but i cann't find it in China
I want download a ebook, but i cann't find it on Web.Can
anybody tell me where i can download a ebook?
Thanks~~
.
|
|
|
|
|
Hi All,
After reading Michael Dunns WTL articles I want to convert my ATL/MFC COM Dlls to ATL/WTL ones.
Building the DLL from base setting I have built a standard ATL project and then added the required WTL #includes as per the examples in Michaels articles. I have changes the CComModule to CAppModule and compiled. Everything works a treat!
I am little bit confused though an where to exactly define/create my CMessageLoop object.
Should I do this in the DLLMain function?
<br />
extern "C"<br />
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID )<br />
{<br />
if (dwReason == DLL_PROCESS_ATTACH)<br />
{<br />
_Module.Init(ObjectMap, hInstance, &LIBID_WTLHISTORYLib);<br />
DisableThreadLibraryCalls(hInstance);<br />
<br />
CMessageLoop* pLoop = _Module.GetMessageLoop();<br />
<br />
ATLASSERT(pLoop != NULL);<br />
pLoop->AddMessageFilter(this);<br />
pLoop->AddIdleHandler(this);<br />
}<br />
else if (dwReason == DLL_PROCESS_DETACH)<br />
_Module.Term();<br />
return TRUE;
}<br />
What the DLL is to do is:
Have however many classes required, each implementing whatever COM interfaces that they need too
Do there thing and return back to Calling Application.
Am I in the right ballpark or because it is a DLL each COM implemented class has its own map... like below
<br />
class ATL_NO_VTABLE CMyReport: <br />
public CComObjectRootEx<CComSingleThreadModel>,<br />
public CComCoClass<CMyReport, &CLSID_MyReport>,<br />
public ISupportErrorInfo,<br />
public IHistoryReport,<br />
public ICommand<br />
{<br />
public:<br />
CMyReport();<br />
~CMyReport();<br />
<br />
DECLARE_REGISTRY_RESOURCEID(IDR_MYREPORT)<br />
<br />
DECLARE_PROTECT_FINAL_CONSTRUCT()<br />
<br />
BEGIN_COM_MAP(CMyReport)<br />
COM_INTERFACE_ENTRY(IMyReport)<br />
COM_INTERFACE_ENTRY(ISupportErrorInfo)<br />
COM_INTERFACE_ENTRY(ICommand)<br />
END_COM_MAP()<br />
<br />
BEGIN_CATEGORY_MAP(CMyReport)<br />
IMPLEMENTED_CATEGORY( __uuidof(CATID_MxCommands))<br />
END_CATEGORY_MAP()<br />
<br />
public:<br />
STDMETHOD(get_Enabled)(VARIANT_BOOL * Enabled);<br />
STDMETHOD(get_Checked)(VARIANT_BOOL * Checked);<br />
STDMETHOD(get_Name)(BSTR * Name);<br />
STDMETHOD(get_Caption)(BSTR * Caption);<br />
STDMETHOD(get_Tooltip)(BSTR * Tooltip);<br />
STDMETHOD(get_Message)(BSTR * Message);<br />
STDMETHOD(get_HelpFile)(BSTR * HelpFile);<br />
STDMETHOD(get_HelpContextID)(LONG * helpID);<br />
STDMETHOD(get_Bitmap)(OLE_HANDLE * Bitmap);<br />
STDMETHOD(get_Category)(BSTR * categoryName);<br />
STDMETHOD(OnCreate)(IDispatch * hook);<br />
STDMETHOD(OnClick)();<br />
<br />
private:<br />
};<br />
Thanks for your help in advance
cheers
Bryce
|
|
|
|
|
CMessageLoop is a WTL class, and _Module has to have message loops added to it explicitly. IOW there is no API or method that says "give me some object representing the EXE's message loop"
Also, _Module is per-module (thus the name), unlike MFC DLLs where several DLLs can share the same CWinApp object. So unless you control the EXE as well, the DLL has no access to the EXE's message loop. If you do control the EXE too, I guess you could pass a pointer to the DLL, although it wouldn't be possible to get to it in DllMain() ; you'd need some other exported initialize function that the EXE would call.
Now, if you create your own UI threads in the DLL, then you control the message loop and you can set up the CMessageLoop object like you want.
--Mike--
Ericahist [updated Oct 26] | CP SearchBar v2.0.2 | Homepage | RightClick-Encrypt | 1ClickPicGrabber
If my rhyme was a drug, I'd sell it by the gram.
|
|
|
|
|
Hi,
If I use a stl deque as a buffer between two threads. If thread A would only push at the back and thread B would only get and pop from the front. (Both without locking) And I would make absolutely sure tha at least one element stays in the deque as a delimiter. Would I run in to any issues that could cause data corruption or racing conditions?
If I would run into problems is there another way to make sure that thread A can always push its data without having to wait? (it has a time critical task)
Thanks a lot in advance,
Erik
|
|
|
|
|
I think it is implementation specific - but I would normally put here some locking mechanism - it's shared resource between two threads - it means, say on two processor machine you can have half pushed object in a dequeue and in the very same moment second thread running in another processor receives that half baked object and consider that it's complete - where it can lead noone knows...
How to do it without waiting in A thread - that depends on your requirements - e.g. I can imagine a mechanism where thread A makes some batches (queue of commands say) and when there's some free time or the queue reaches some maximum size it's marked as complete (event signalled e.g.) and pushed to the thread B for processing, while A thread creates new (or uses previously created) queue for pushing...
just an idea, maybe there can be dozens of other solutions, it really depend on the requirements you have for the processing.
hope this helps
|
|
|
|
|
One solution is a critical section for single process and a mutex for multiple processes. Check the size of the container.
Kuphryn
|
|
|
|
|
I don't think that you can do this without using a critical section. You have to synchronize access in some way. I'd be interested to hear more on your plan for this delimiter object-- how do you think that it will solve the problem of A and B both accessing the same memory at the same time? I'm really curious.
One tactic that you can take is to buffer things a little before even putting them in the queue. A can stack up a few things destined for the queue, and just copy them into the queue on a scheduled basis or when the buffer gets full. In my experience, it will still have to lock, but this can greatly decrease the per-element synchronization overhead. Of course, this can mean some tradeoffs like extra memory overhead, and another drawback is that the elements aren't immediately made available to thread B.
Thank you.
Jeff Varszegi
|
|
|
|
|
Well my thought was because a deque is basically made up out memory ellements with two pointers one to the next element and one to the pervious. So if you make sure one or two elements always stay in the deqeu the two threads wil never access the same memory space (because each thread only operates at one end of the queue). At least that is my theory please correct me if I'm wrong.
But apperantly it's safest to find some locking meganism, the problem is just that thread A is reading from a serial port, so I never really know whether I have time to wait for a lock on the deque, or I'll mis incomming bytes. Secondly it's rather important to get all bytes in de deque as soon as possible (I need to register when they got in), so buffering them is not really an option.
Thanks for all reactions,
Erik
|
|
|
|
|
There are many approaches. Depending on what you are doing, have a searh on google for Producer/Consumer, Bounded Buffer and Multiple Reader/Writer as thread syncronisation methods. If you have just two threaads, then all you should need is a Mutex or a Critical Section (which is a faster method for all in process - Mutex can do cross process).
If you want to limit the size of the buffer i.e. the writer can outrun the reader, then have a look at the bounded buffer.
Personally for lots of different patterns with good descriptions and full working implementations is a book called "Multithreaded Programming with Win32" written by T.Q. Pham and P.K. Garg.
Its even demonstrates a multithreaded quicksort.
"Je pense, donc je mange." - Rene Descartes 1689 - Just before his mother put his tea on the table.
Shameless Plug - Distributed Database Transactions in .NET using COM+
|
|
|
|
|
Hello,
I am using eVC 3.0 and trying to build a database application. I am using an #import of arm\adoce31.dll. It is giving me a linker error [CODE]unresolved external symbol "class _variant_t vtMissing"[/CODE].
I have read in one section of MSDN that vtMissing is suppiled by #import. Do I have to include some more libraries ?
Many thanks in advance.
Regards,
Amit
|
|
|
|
|
If this is the only value you are missing
just define your own:
vtMissing.vt = VT_ERROR;
vtMissing.scode = DISP_E_PARAMNOTFOUND;
|
|
|
|
|
I am brand new to STL so please bear with me. I am creating an item Label based on an abstract class button. In code in the first segment works for me as expected. But In the second part I was not expected to have to cast (delete (Label*)pB; ) as noted below. When I don't cast the destuctor does not get called.
So, finally my question. As I am going thru the vector should I have to know each type of thing being deleted so I can cast it accordingly or am I approaching this all wrong?
In my application I was only using ( delete pB; ) and this is causing a memory leak. The only solution I see during clean up I query each object being destroyed for its type then call the appropriate code.
for example
if( objecttype == Label )
delete (Label*)pButton;
else if ( objecttype == Image )
delete (Image*)pButton;
This seems wrong to me. Please enlighten me.
// First part of code example
std::vector<Button*> vButtons;
pButton = new Label( ... );
vButtons.push_back( pButton );
// Second part of code example
int count = vButtons.size();
if( count > 0 )
{
std::vector<Button*>::iterator it;
Button *pB;
for (it = vButtons.begin(); it != vButtons.end(); ++it)
{
pB = *it;
if(pB != NULL)
{
delete (Label*)pB;
pB = NULL;
}
}
vButtons.clear();
}
|
|
|
|
|
Did you declare your destructor (in the button class) as virtual?
John
|
|
|
|
|