|
Steen Krogsgaard wrote:
I'm not sure, but since it's function pointers it makes most sense to me that it is in the code segment. Its definitely not in stack or heap. The vtable is created at compile time, as there is only one vtable per class, and this vtable is shared by all instances of that class
Don't take it personally, but that's not quite right
The vtable is part of an object - each object has its own copy. It is stored as part of the object's data, and is initialised as part of the object's construction, before the constructor is called (disassemble the constructor code to see where). It's initialised by copying the data verbatim from its class's class-specific vtable.
The reason it's got its own copy is so that virtual functions work. Take the following code:
void myFunc(MyBaseObject* objPtr)
{
objPtr->myVirtualFunction();
}<br/><br/>myFunc(new MyDerivedObject); If the vtable was per class, then this wouldn't work. When myVirtualFunction was invoked, the compiler would have to know what type of object objPtr was so it could invoke the correct implementation of the function. Since the whole point of polymorphism is that compiler doesn't have to know what type of object it's got, this simply will not work. If the vtable is per-object, all the compiler has to do is lookup in the object's vtable the function pointer using the correct table index and call it. The compiler has to make sure that each implementation of a virtual function is given the same index into the table for all the classes derived from the same base class. So in essence, this call translates to something like:
(*objPtr->vtable[myVirtualFunctionVTABLEindex])() Hopefully that clears things up a little
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Ryan Binns wrote:
Don't take it personally, but that's not quite right
Unfortunately I'm quite sure I'm right (although being so sure of one self always comes with the risk of making a complete fool of one self by actually being wrong )
Look at MSDN, "C++: Under the Hood" by Jan Gray (it's from 1994 and in my October 2001 version of MSDN, but I believe it's still holds true). Each object contains a pointer to the vtable, but not the vtable itself. This pointer is used at runtime to look up the adress of the virtual function.
It wouldn't make much sense to have a per-instantiation vtable. Two objects of the same type will per definition have the same vtable (otherwise they would not be of the same type). What polymorphism does is to allow you to delay the linking so that you don't have to know the exact type of the object in order to call functions on it. However, the compiler will have to know what index in the vtable to use at compile time, that's why the base class vtable entries preceeds the derived class vtable entries. And that's why multiple inheritance is such a mess!
This is of course compiler-implementation dependent, but I'm pretty sure that the above holds true for VC++.
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
Aaaah, I've been fooled by MS' double indirection :P. My fatal assumption was that VC++ would be basically the same as other compilers
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Allright.
Are you absolutely sure that other compilers make a copy of the vtable for each instantiated object? It seems such a waste of resources. Imagine having a class with 25 virutal methods, thats 100 bytes for each vtable, and having objects of this class in a large array, say 10000 objects, thats 1MB just for vtables - and identical vtables, I might add. From what I've been able to dig out with Google, GCC also uses pointers to vtables, and this reference http://www.awprofessional.com/articles/article.asp?p=26063&seqNum=3[^] states that not only all C++ compilers, but all compilers for all languages using virtual functions are implemented with at pointer to the vtable in the object. Do you have any references for compilers that use the one-vtable-per-object model? I'm just curious!
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
|
Hi all,
My application has two classes (class A and class B), both of them are CDialog class and have message handling capability. Now, I want to write code in class A to ask class B to run its function(RunTimer) which run SetTimer() function to do actions periodically.
My idea is here.
In class A cpp file, I have:
ClassB myclassb;
void test()
{
myclassb.RunTimer();
}
In class B cpp file, I have:
void RunTimer()
{
SetTimer(1000, 3000, NULL);
}
I can compile my program. However, when I run my program, I get exeption error. Is it my idea is wrong? How can I ask class B to handle message?
Thanks
|
|
|
|
|
The first solution that comes to mind is enable Class B to handle user defined messages. This would enable Class A, or any other window for that matter, to send instruction messages to Class B, such as activating the dialogue's timer function.
The only concern is the modality of your dialogues. I have used this method flawlessly in modeless dialog, but I'm not sure how it would work in a modal dialog, since the blocking mechanism my interfare with the sent messages. Maybe someone could verify if this method still works for modal dialogues.
Joseph Newcomer's excellent essay[^] on window messages is a must read.
I Dream of Absolute Zero
|
|
|
|
|
I have a table represented by a control CListCtrl. I want to merge all cells from a specific row and to insert in the new created cell a text. If anybody knows a solution please tell me. Thanks.
BujCat
|
|
|
|
|
Here's my thought "from the hip"...
Loop through all the "SubItems" of a particular "Item" .appending() each sub-item's text to a CString. Now you have your merged text.
If you want to create a new column (not sure what you mean by "cell"), then you'll have to CListCtrl.InsertColumn(), and then redraw the control.
Hope this helps you find the MSDN references you'll need.
thanks,
JennyP
|
|
|
|
|
I have defined "cell" the intersection between a row and a column. My list control have a black grid between cells.
I don't know if you understand me. I want to merge all cells from a row(to merge all columns) and to insert a CString in this row.
I try a lot but I don't have resolved the problem yet
Thanks
BujCat
|
|
|
|
|
Hi everybody,
I have a problem, which I could not solve myself and I hope somebody has made some experiences with CMetaFileDC. First of all: My Code works on onscreen-DCs and what comes out of my printer looks exactly as I want. My only problem is rendering a metafile to a print-preview-DC. The result is always way to large and does not fit the page. It seems that the preview-dc behaves like a printing-dc and PlayMetaFile ignores that.
Some example code (like mine but without unnecessary details):
<br />
CSize ext(cx, cy);<br />
pDC->DPtoHIMETRIC(&ext);<br />
CMetaFileDC mdc;<br />
mdc.CreateEnhanced(pDC, 0, CRect(CPoint(0, 0), ext), 0);<br />
<br />
drawObjects(mdc);<br />
<br />
ext.SetSize(pDC->GetDeviceCaps(PHYSICALWIDTH) - 2 * pDC->GetDeviceCaps(PHYSICALOFFSETX),<br />
pDC->GetDeviceCaps(PHYSICALHEIGHT) - 2 * pDC->GetDeviceCaps(PHYSICALOFFSETY));<br />
<br />
HENHMETAFILE hMf = mdc.CloseEnhanced();<br />
CRect bounds(CPoint(0, 0), ext);<br />
pDC->SaveDC();<br />
pDC->SetMapMode(MM_ANISOTROPIC);<br />
pDC->PlayMetaFile(hMf, &bounds);<br />
pDC->RestoreDC(-1);<br />
<br />
DeleteEnhMetaFile(hMf);<br />
If necessary I can make some screenshots of that effect.
Thanks for reading ,
Christian
|
|
|
|
|
Hmmm, i tried to render the metafile to an offscreen-dc and then BitBlt it to the preview-dc. Same effect. I have no idea what to do...
|
|
|
|
|
How do I export a class written in C++ to a VB project?? How do my VB declare and use this class??
|
|
|
|
|
CLASS .
Exporting Function from C++ DLL is easy but for exporting CLASS you have to create COM DLL ,as i think soo.
"I Think this Will Help"
[Vote One Here,.....]
<h5
alok gupta="" <br=""> visit me at http://www.thisisalok.tk
|
|
|
|
|
is there any way to append a CString [] to another CString [], can anybody help me?
thanks to all.
|
|
|
|
|
|
CString behaves much like a normal C++ string, hence
you can use:
CString strHello = "Hello";
CString strThere = " There";
CString strAppend = strHello + strThere;
Is that what you had in mind?
Cheers,
David
|
|
|
|
|
how can i validate date input from user, i accepts that date in to a CEdit derived control, i want to check whether the user enter the in right format or not ( my required format is DD/MM/YY). any idea ?
Thanks in advance
Ninety-eight percent of the thrill comes from knowing that the thing you designed works, and works almost the way you expected it would. If that happens, part of you is in that machine.
|
|
|
|
|
Use CDateTimeCtrl . It can be validated.
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
Doing it "old school", you can use a call to sscanf(...) , which was designed for scanning a formatted string. For example, if you would build a string using printf(...) with a format string of "%02d/%02d/%02d" , you would scan that string back with that same format string, and check the return value of sscanf(...) to make sure you scanned out three tokens/values.
That would help you verify the format, but not the data... For example, scanning "99/88/77" would be successful, even though it is an invalid date.
Peace!
-=- James If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Tip for new SUV drivers: Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! DeleteFXPFiles & CheckFavorites
|
|
|
|
|
A nice article on codeproject site, "editable date time control", using date time edit control and programmer is validating the date based on format, if you check his code, you may get idea about date validation from edit control.
Anand
|
|
|
|
|
I am having an issue with malloc on Win2000 and WinXPPro. I am trying to repeat a real world scenario here. I have a loop that keeps calling malloc until it fails (use all virtual address space).
1) malloc 1100 rand() size blocks between 0 and 32 bytes.
2) malloc nSize block
3) malloc another nSize block
4) free 2)
5) repeat from 1 until any malloc fails
6) free all allocated memory
After process creation if use nSize>520184, this will continually use all virtual space until use nSize<=520184. Now use nSize>520184 will allocate 1-25 blocks then malloc fails. I can continually use nSize<=520184 and use all address space.
Basically once I have filled the address space with blocks <=520184 I can no longer use blocks >520184.
Anyone got any thoughts
|
|
|
|
|
Maybe you can refer to the intersting article about the allocations in MSDN:
Search "globalalloc" then rubrik "Allocations memory; the old-fashionned way"
Hope this will help you.
|
|
|
|
|
It sounds like your allocation pattern is causing heap fragmentation. I'm not sure whether Windows 2000 or XP automatically coalesce adjacent free blocks, or whether they leave those blocks as separate blocks. I suspect that if the code from the VC6 runtime library was used or adapted, they only join the block being freed with the next block if that is also free.
You can force a full coalesce of the heap by calling _heapmin . The documentation currently states that it's only supported by Windows NT but my reading of the source indicates it should also work on 2000, XP and 2003. Under the covers this function calls HeapCompact .
One strategy to prevent the fragmentation in the first place is to allocate different size blocks, or blocks with different lifetimes, from different heaps. You can create your own heap using HeapCreate .
The heap code is really meant for small variable-size blocks. If you're creating 512KB buffers, you might be better off calling VirtualAlloc directly.
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Thanks for your thoughts. Different size blocks or different heaps is not applicable here. I have modified the loop to use malloc for small blocks and VirtualAlloc for the big blocks. This gives me more stability and memory usage. But, there is always one, this code is ANSI C only, so no access to VirtualAlloc.
If it is fragmenting memory then should this not be a gradual degredation? NOT as stated, use <=520184 and immedialty you cannot alloc more? There is something odd happending in the MS implemenation of a VMM!
|
|
|
|