It's still kind of vague to me what you are doing. Normally, you call the virtual function using the base class pointer. I don't see any reason why having a derived class pointer would cause a problem. But as a design critique, the purpose of virtual functions is to be able to hide dependencies by using the base class pointer to interface to the object. That way, the users of the object are only bound to the base class at compile time. During runtime, the user is unaware that the derived class actually implements the function. There isn't much point in creating a pure virtual function if the users of your object are calling the function from a derived class pointer anyway. That defeats the purpose of run time binding. You should have some kind of factory build the classes so that the dependency on the derived class is controlled and limited. The actual users of the class that call the functions should get pointers of the base class type from the factory. Then if the implementation needs changed in the future, not as many pieces of your program have to recompile when you make changes. Maybe you could show us your class declarations and a few code snippets where the function calls are made to give us an example of what you are doing.
digwizfox
Posts
-
Pure Virtual Function Call -
Convert CStringFor future reference, take a look at the inet_addr function in the MSDN library. I can't believe there isn't built in global c runtime functions for parsing an IP address in this day and age. But if you are programming with MFC or windows, you can use this windows function. I hate the sscanf method myself. It seems wonderful on paper but there seem to be all kinds of weird issues when I try to use it. It never worked well for me as a validation tool for any kind of number. I always use the cruntime methods such as strtod for taking strings and validating them as actual numbers and converting them into an int value (for instance). Unfortunately, I don't see a c-run time method for IP addresses that would be more portable. Since I am a windows programmer, I have to settle for the windows libraries to provide this capability. Shawn
-
Pure Virtual Function CallI have no idea what you are asking. Could you be more specific in describing your problem? What do you mean, when does it occur? It occurs when someone types in the function call from another function and runs the program. Is there a compile error or weird runtime behavior that you are debugging?
-
CFormView window can never be on top of CDialog. Why? How can I change this?We have a CFormView based application. Within this application, some have created CDialog classes and so we have a mixture of window types. Some of our modal windows are CFormView based and some are CDialog based. The CDialog windows always have priority over the CFormView based windows. Even when I click on a window that is a CFormView, the title bar activates and the window is selected, but it cannot be brought to the front to display over the CDialog windows. Does anyone know what properties I have to enable or disable to change this behavior? I need CFormView windows to display overtop of the other independent CDialog windows. Best Regards, Shawn D. Fox
-
question on critical sectionAnother concern is a possible program crash. When vectors are changed, all iterators are invalidated. So if the main function has an interator and is in the process of reading the data, the thread could interrupt and add something to the vector. Now the main function has an invalid iterator. The problem with not using synch methods is that the errors may not be noticed for months. You could think all is well and then one day, your program crashes while doing the same thing it's been doing all along. Shawn
-
Checking if a folder exists...I implemented a function for something I worked on that checks to see if a file exists, but the documentation indicates that it works for directories as well as files. So take a look at this. It's worked well for me and seems very reliable. It seems different than the other responses, so if you are still looking for an alternative; here you go. I simply created a CString as input. The CString may contain wildcard characters such as * or ?. FindFirstFile is a global method and can be found in the MSDN library so go ahead and look it up and feel free to cut and paste this function and play with it to see how it works. It's pretty simple. BOOL CDXControlDlg::IsNewFile(CString& sPath) { // Check if files exists already WIN32_FIND_DATA fileInfo; HANDLE hFile = ::FindFirstFile(sPath, &fileInfo); if (hFile == INVALID_HANDLE_VALUE) { // File not found return TRUE; } else { // File exists. ::FindClose(hFile); return FALSE; } } Best Regards, Shawn
-
classes and namespacesYou do not have to qualify type with the name of the class since it is declared inside the class. The original declaration of the Type enumerated variable was fine. Shawn
-
Design Pattern Discussions??Where can I find a good discussion board on Design Patterns, as they relate to object oriented programming? It doesn't have to be C++ specific. I've been reading the book Design Patterns: Elements of Reusable Object Oriented Design and although the class diagrams and concepts are interesting, I have some implementation questions, I'd like to ask about them.
-
Determine text file or Binary fileI don't think so. This wouldn't make any sense to me. After all, a binary file appears as garbage in a text editor because the bytes will not map to ascii to form any kind of intelligible sentence in any language. The text editor doesn't care if the file you tell it to open is binary or not. It will just read the file and try to map the bytes into ascii and display whatever random characters the data happens to map to. If there were an automatic function for doing this, the people that wrote notepad and wordpad probably would have popped up an warning message reading, "warning, processing binary file"; or something like that. All files are binary files, in my mind. It just so happens that a text file is a special kind of binary file where each byte maps to an appropriate ascii symbol to form intelligible letters/numbers/symbols. Even the carriage returns and line feeds are simply bytes of data that map to the appropriate ascii symbol. I think writing an algorithm to guess if something is good enough to be a text file would be awfully difficult if not impossible. You'd have to read each byte in and make a lot of assumptions about the data.
-
Access violation reading location 0xcdcdcddd.For future reference, it sure would help to see some code snips of your class declaration, constructor implementation, and maybe some snips of where the instantiated object is used. Regards, Shawn
-
Memory Management across DLLsSo what's the verdict? This is a really interesting thread and I'd like to know if any conclusions were reached. Based on Peter's description, the memory is getting allocated in the program. Peter, you said that class A was embedded in class B right? And you said that class B was instantiated in the main application right? So essentially, the library contains the class declaration for A but the main application project contains the actual code that runs and instantiated objects, deletes objects, displays data to the console, and so on and so forth. Is that right? I do this all the time with no problems. The class in the library needs to be exported so that the program can compile and link properly. Obviously you've done that else it wouldn't have compiled and linked. But I have never instantiated something in a DLL and then passed the destruction responsibility to another DLL or .exe. That would seem like a strange implementation to me; anyway. I don't know what you mean by the "Delete" statement defined in library.dll. The delete statement is basic C++ syntax. It's not defined in the DLL. I don't know what you mean by saying that. It sounds like your library.dll is simply declaring the class. That has no bearing on where and how the class can be created or destroyed. Any project (dll or the main project) should be able to link to the class declaration in your library, instantiate it's own version of the object and subsequently delete it. Is there any special code in the destructor of Class A? It'd be nice to see some code snips of class B and A so we have some idea of the complexity of the classes, especially what specifically, is being done in the destructor of each class. Oh and some snips of code where you instantiate and delete the object would be nice to see as well.
-
Virtual DestructorsI like this question. The other posting did a good job of explaining why the virtual destructor is needed. The reason you don't need a virtual constructor is that you are specifically telling the compiler what you want to instantiate. You write int i = 10; CBase* pPointer; pPointer = new CChild(i); The concept of virtual functions is also described as dynamic run time binding. So the idea is that you call a function on the fully instantiated object and the system is smart enough to realize that since a function is virtual, the child class version of the function is called first. Then the child class can execute it's own code and may or may not ivoke the base class version of the function as well. So virtual functions don't make sense during the construction process. The child class has to call the constructor for the base class from within it's own constructor. Once the construction of the class is complete, you can use the base class pointer to call virtual functions. If you tried to call any virtual functions from either of the constructors, I'm not sure what would really happen. I wouldn't recommend trying this as it really makes no sense. Seems like it would be an undefined operation that may or may not cause a crash. Shawn
-
Access violation reading location 0xcdcdcddd.is the debugger pointing to the line of code that calls lockWait()? Are you sure that m_pSendLock was initialized properly? Usually, that type of crash is associated with a pointer that is A) uninitialized (not set to NULL by default) and B) never set to actually point to an object. xCDCDCDDD is the kind of number that variables sometimes get set to if they were never initialized to 0 or NULL in a class constructor. Always initialize pointers to 0. In this case, obviously, you have to set the pointer to point to some valid object. Are you doing something like the below code to setup your pointer somewhere? m_pSendLock = &theSemaphoreObject; or m_pSendLock = new CSemaphore; If so, what specifically are you doing to set the pointer? Is the crash occurring when your application exits? Another kind of situation that occurs is when you have a thread that doesn't terminate before your class is destroyed (on exit). The object gets destroyed but the thread continues to execuate and then trys to call a function with an invalid pointer.
-
ON_WM_KILLFOCUSLet me clarify my question. I need to understand why visual studio 6.0 was able make the static_cast so that I can understand how to get this code to work under visual studio.net. Obviously, visual studio .net is more standards compliant since it is complaining. Since I can't imagine how the compiler performs the implicit cast from CWnd* to UINT iResourceId, I have no idea how to do the cast manually. There must be a way.
-
ON_WM_KILLFOCUSThe following code snips relate to code that successfully compiled using Visual Studio 6.0. This same implementation does not compile in Visual Studio .Net 7.0. Here is the error message ConfigTSAControlsFView.cpp(200) : error C2440: 'static_cast' : cannot convert from 'void (__thiscall CConfigTSAControlsFView::* )(UINT)' to 'void (__thiscall CWnd::* )(CWnd *)' //Function Declaration afx_msg void OnKillFocus(UINT uiCtrlID); //Message Map Entry ON_WM_KILLFOCUS() //Function Implementation void CConfigTSAControlsFView::OnKillFocus(UINT uiCtrlID) { //the code } Now this is what confuses me the most. The MSDN library implies that the OnKillFocus method takes a CWnd*, not a UINT. Visual studio 6.0, somehow was able to compile this and perform a cast. However, Visual Studio .net is complaining that the static_cast is not possible. So can someone explain to me how visual studio 6.0 can make the cast and why visual studio .Net cannot? The uiCntrlId is used in a switch statement so the actual value being used is equal to the resource Id of the window. How did visual studio cast from a CWnd* to a resource Id automatically? This seems like quite a stretch. If anyone has any ideas, I'd appreciate it. Personally, I think the error message makes perfect sense. Of course the compiler won't cast from a CWnd* to a UINT that has a completely different meaning. I just can't imagine how the code ever compiled and worked with visual studio 6.0. The other thing is that if I change the code to use a CWND*, then it seems to invalidate the existing switch statements, within the function, that expects a controller id.
-
Resizing a static variableThe problem was that I was trying to implement the aforementioned code in my OnInitDialog method, prior to calling CDialog::OnInitDialog like so BOOL UDxFilterDlg::OnInitDialog() { //NO! NO! Can't do this here. Must call //CDialog::OnInitDialog(); first! CRect rect; mGroupBox.GetClientRect(&rect); mGroupBox.SetWindowPos(NULL, 0, 0, rect.Width(), (rect.Height() - (rect.Height()/3)), SWP_NOMOVE | SWP_NOZORDER); CDialog::OnInitDialog(); //Resize the group box below this point and it works fine! //..rest of code }
-
Html help filesCheck out this website. http://www.mvps.org/htmlhelpcenter/ I found the sample projects to be useful even though the tutorials are not that great. I was looking at htmlhelp recently and did not get much help from the newsgroups nor could I find much on the web. But the C++ example here was quite useful, so you can download it, compile it, and use the debugger to figure out what is going on. When you use the htmlhelp api to to tell your program to display a particular help file, within the htmlhelp window, it will expand the table of contents for you. I don't do anything specific to make it happen; it just does it. I implemented context help to allow me to press the '?' button on the upper right of my window and then when you select a dialogue item, it will call the html api function like so... That is one example; you might have switch statements or some pattern for interpreting the ID of the resource and then calling the appropriate version of ::HtmlHelp. Notice the '::'. I am using the global api function. There is an HtmlHelp function built into the mfc classes as well and I do not use those. I use the global function. Why? Cause it just works for me, I guess. Here is some example code. You see I am responding to the OnHelpInfo method in my dialog class. I setup the help path to my .htm file and then when I call ::HtmlHelp at the bottom, it will open the main html help window with the table of contents displayed and it will expand them to the file I am telling it to display specifically. Hope that gets your started. That's all I know; and the htmlhelp documentation, that I have found, really stinks. So I learned how to do things using the example code on the aforementioned website. I still have no idea how it really works. BOOL CDataReductionDlg::OnHelpInfo(HELPINFO* pHelpInfo) { CWinApp* theApp = AfxGetApp(); //Get the help file name CString sHelpFilePath = theApp->m_pszHelpFilePath; //sHelpFilePath += _T("::/hid_sc_size.htm"); switch(pHelpInfo->iCtrlId) { case IDC_START_DAY: case IDC_SPIN_START_DAY : case IDC_START_HOUR: case IDC_SPIN_START_HOUR: case IDC_START_MINUTE: case IDC_SPIN_START_MINUTE: case IDC_START_SECOND: case IDC_SPIN_START_SECOND: case IDC_START_MILLISEC: case IDC_SPIN_START_MILLISEC: case IDC_END_DAY: case IDC_SPIN_END_DAY: case IDC_END_HOUR: case IDC_SPIN_END_HOUR: case IDC_END_MINUTE: case IDC_SPIN_END_MINUTE: case IDC_END_SECOND: cas
-
Resizing a static variableHere is a description of my problem. I have a modal dialogue window. In my OnInitDialog function, I may have to adjust the size of the window and it's contents manually because sometimes when the dialogue is constructed, an argument is passed into the constructor that turns off the display of certain controls within the window. So when the controls are off, I want to change the size of the window and remaining controls so that everything looks nicer (I don't want a huge blank spot in the middle of the window in this case). So everything was working fine; I tried changing the window size of the dialogue and that worked fine. I know I can move buttons around and adjust them just like you do when a dialogue box is resizable by the user. But how do I resize a static group control? The group box is a border rectangle that surounds the controls and is just inside of the main dialogue. When I run the below bits of code, the GetClientRectangle function causes my system to crash. The group box is a CStatic control which inherits from CWnd. So it must have a rectangle, within the object, to describe it's coordinates. So why does GetClientRect fail? Is this not a valid function call for a CStatic control? If not, how do I get it's coordinates? mGroupBox.GetClientRect(&myRect); //Crash!!! //This would then adjust the height by 25% mGroupBox.SetWindowPos(NULL, 0, 0, myRect.Width(), (myRect.Height() - (myRect.Height()/4)), SWP_NOMOVE | SWP_NOZORDER);
-
Huge Text FilesGood question. Also keep in mind that when it comes to "HUGE", say > 100MB of text data, I would not recommend using notepad. Notepad is terribly inefficient for some reason. Wordpad handles large text files, for viewing, much more effectively.
-
HTML Help: Using F1I'm getting some weird results in my MFC application when I press F1 over a menu item. For some reason, I get an error "cannot open Help" when I press F1 over certain menu items. It seems totally random. I never did anything special to make it work for any of the items anyway. When I created the application, I enabled HTML help. I've been able to change the table of contents and add help files. But one thing I have not figured out is how to control what pops up when F1 is pressed. For most of the menu items, it works fine. For instance when I put the mouse pointer over the view -> status item and press F1 it immediately brings up the status help screen with the Main Help dialogue. When I do the same over File -> open or Help -> help topics I get the error message. I'm not finding anything specific in MSDN library. What is the trick here? I know I can handle a message to respond to F1 and have done this. But I was hoping to find another way. I mean after all, 95% of the menu items work fine when I press F1 but I have no idea what gives for the very few where it doesn't work. Also, in one of my dialogues I have written code for the function: HtmlHelp(NULL, HH_DISPLAY_TOPIC); Now this will display the main help window. The NULL could be a pointer to something. I don't know what it is a pointer to. Does anyone know? How do I use the first argument to cause a specific help topic to display within the help dialogue? I've tried a few things and don't think the documentation is entirely clear on what I am supposed to point the function to. Any ideas? Thank you, Shawn