|
I am not familiar with the PComm library. User defined events can be created using the ::CreateEvent() Windows API. Check the documentation on the other Synchronization functions as well.
Again I apologize for my unfamiliarity with PComm, but the ::WaitCommEvent() API can be used when opening Serial ports with the ::OpenFile() API. Hope this gives you somewhere to start.
Happy Hunting...
|
|
|
|
|
Hi
My system has an employee hierarchy with CEmployee at the top. I have several child classes - CSalesman, CStaff, CWorkers.
I can use polymorphism to calculate for example salaries so I have array of CEmployee pointers. I can call the calcSalary() function on these pointers and the right function for the child class gets called. One of my employee types has a member function getCommission(). Using my array of base class pointers, I want to call this function on all the CSalesman objects and not the others. I also want to ennumerate each type so I can find how many CWorkers I have for instance.
Can someone suggest a best practice for this?
Thanks
|
|
|
|
|
Add a mamber variable in your base class: it will be an ID that will identify the object type. Something like this:
class CBaseClass<br />
{<br />
.....<br />
....<br />
....<br />
<br />
private:<br />
int m_ClassID;<br />
enum<br />
{<br />
Worker,<br />
Salesman,<br />
Staff<br />
};<br />
}
In the constructor of all your child classes, initalize this ID with the correct value.
CWorker::CWorker()<br />
{<br />
m_ClassID = CBaseClass::Worker;<br />
}<br />
You can add a function to get this Id and so, using a pointer to CBaseClass, you can know the type of Employee it is.
Hope this helps.
|
|
|
|
|
That would work, but it means that you couldn't then add derived classes without having to change your base class.
An alternative is to use the IsKindOf() member function of CObject , which means of course, that you would have to derive your base class from CObject , but that may add useful features such as serialisation and dynamic creation.
More here:
MSDN - Accessing run-time info[^]
"Oh, I'm sick of doing Japanese stuff! In jail we had to be in this dumb kabuki play about the 47 Ronin, and I wanted to be Oshi, but they made me Ori!"
|
|
|
|
|
Yes, you just have to add new enum types for each new child class you want to create.. But what is the problem ? You have to recompile your project in both cases. The only difference is that in this case all the child classes will be recompiled...
Can you explain a little bit more here ? Thanks
|
|
|
|
|
Yes, every time you add a new derived class using your suggestion you have to make a change to the base class. I'd respectfully suggest that this isn't "best practice", as it breaks the concept of encapsulation and effectively prevents the use of late/dynamic binding. However, in the context of a single project, your method would work, which is why I suggested mine as an alternative and not a correction
"Oh, I'm sick of doing Japanese stuff! In jail we had to be in this dumb kabuki play about the 47 Ronin, and I wanted to be Oshi, but they made me Ori!"
|
|
|
|
|
also, have a look at RTTI ( runtime type information ).
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
It depends on how you think. Some people like RTTI, some people like home grown (enums and typecodes), other people don't use it at all. To prevent casting, and to get the cleanest possible OO design use the 'Visitor' pattern from the gang of four book.
The general idea is you use double-dispatch to sort out the type information
#include <iostream>
#include <vector>
using namespace std;
class Visitor;
class CEmployee
{
public:
virtual void accept(Visitor& v);
virtual void foo()
{
cout << "employee" << endl;
}
};
class CSalesman : public CEmployee
{
public:
virtual void accept(Visitor& v);
virtual void getCommision()
{
cout << "commision" << endl;
}
virtual void foo()
{
cout << "salesman" << endl;
}
};
class CStaff : public CEmployee
{
public:
virtual void accept(Visitor& v);
virtual void foo()
{
cout << "staff" << endl;
}
};
class Visitor
{
public:
virtual void visit(CEmployee* pA) = 0;
virtual void visit(CSalesman* pB) = 0;
virtual void visit(CStaff* pC) = 0;
};
void CEmployee::accept(Visitor& v)
{
v.visit(this);
}
void CStaff::accept(Visitor& v)
{
v.visit(this);
}
void CSalesman::accept(Visitor& v)
{
v.visit(this);
}
class CommisionVis : public Visitor
{
public:
virtual void visit(CEmployee* pEmp)
{
}
virtual void visit(CSalesman* pEmp)
{
pEmp->getCommision();
}
virtual void visit(CStaff* pEmp)
{
}
};
int main()
{
std::vector<CEmployee*> empList;
empList.push_back(new CEmployee());
empList.push_back(new CSalesman());
empList.push_back(new CStaff());
for(size_t i = 0; i < empList.size(); i++)
{
empList.at(i)->foo();
}
cout << "**************************" << endl;
CommisionVis vis;
for(size_t i = 0; i < empList.size(); i++)
{
empList.at(i)->accept(vis);
}
}
If you can keep you head when all about you
Are losing theirs and blaming it on you;
If you can dream - and not make dreams your master;
If you can think - and not make thoughts you aim;
Yours is the Earth and everything that's in it.
Rudyard Kipling
|
|
|
|
|
|
Line 66 should be:
std::vector<CEmployee*> empList;
Maxwell Chen
|
|
|
|
|
Is getCommission() a virtual function? If so, couldn't you have something like:
class CEmployee
{
protected:
virtual double getCommission( void ) { return 0.0; }
};
class CSalesman : public CEmployee
{
protected:
virtual double getCommission( void ) { return 1.5; }
};
class CStaff : public CEmployee
{
}; Now the CEmployee pointers could call getCommission() no matter what type of employee the object referred to.
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
Sounds like a bit of a hack to me, having a function called getCommission() in the base class and all the derived classes, which might only be relevant to one derived class (a CSalesman in this case).
"Oh, I'm sick of doing Japanese stuff! In jail we had to be in this dumb kabuki play about the 47 Ronin, and I wanted to be Oshi, but they made me Ori!"
|
|
|
|
|
what is the best way to debug a win nt service ?
|
|
|
|
|
hi
try
1) Start the service thru SCM MMC IDE
2) Open the project in VC++ IDE
3) Goto Buld --> Start Debug --> Attach to Process
4) Check the 'Show System Processes' button
5) Select ur service from the listbox and click Ok
rgds..mil10
|
|
|
|
|
how to get live stock quote programatically. (live scrip rates)
|
|
|
|
|
hello
can any one solve my bitmap blurring problem
i have one small bitmap which i am loading with loadimage function.But i am loading that bitmap with larger size than what it's original size at that time the bitmap is displaying blurry can any one help to solve the blurring problem
thanks in advance
naresh
|
|
|
|
|
Sorry bro, no one can help u with this.
This is a digital world. U cant do an optical ZOOM to a digital bitmap, lolz
Remember... testing & debugging are always part of programming ...so exterminate those stinking bugs
|
|
|
|
|
What you have is a pixalation problem, unless the displayed size is not a multiple of the bitmap size. When you wish to show a bitmap at a size larger than the original, it should be a multiple of the original bitmap. That way the individual pixels are enlarge and not blured. Example: if you have a 12x12 bitmap then the enlarged version should be 24x24, 36x36, ect...
If you are enlarging to some size that is not a multiple of the original then in will blur and there is nothing that can be done.
Look in the Bitmap & Pallete section of code project for more info..
INTP
|
|
|
|
|
How to delete menu from my application and create and insert another menu. I would like to have two menu resources ( For example IDR_MENU1, IDR_MENU2), and I want to "step" between them dinamically, without exiting the programm. Actually i've already posted similar question about "multilanguage problems", and the menu is the last problem i have .
|
|
|
|
|
your menu is a popup menu or a mainfram menu
|
|
|
|
|
CMainFrame header
CMenu m_menu;
HMENU SetNewMenu(UINT nMenu);
CMainFrame body
HMENU CMainFrame::SetNewMenu(UINT nMenu)
{
m_menu.LoadMenu(nMenu);
m_menu.LoadToolbar(nMenu);
return (m_menu.Detach());
}
Code that sets menu
CMenu* pMenu = AfxGetMainWnd()->GetMenu();
if (pMenu)
pMenu->DestroyMenu();
CMainFrame* pFrame = reinterpret_cast<CMainFrame*>(m_pMainWnd)->SetNewMenu(IDR_MENU1);
ASSERT(pFrame != NULL);
HMENU hMenu = pFrame->NewMenu();
CMenu* pNewMenu = CMenu::FromHandle( hMenu );
ASSERT(pNewMenu != NULL);
AfxGetMainWnd()->SetMenu(pNewMenu);
Ant.
|
|
|
|
|
Thanks, that helped me so much.
Actually i used it in Pocket PC, but using the different way.
I used there CCeCommandBar, and just did this:
AfxSetResourceHandle(hInst);
CMainFrame* pMainFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
pMainFrame->m_wndMenuBar.ResetCommandBar();
pMainFrame->m_wndMenuBar.InsertMenuBar(IDR_MAINFRAME);
pMainFrame->m_wndMenuBar.LoadToolBar(IDR_TOOLBAR1);
Thanks again.
|
|
|
|
|
I'm glad it helped as I have just noticed that I did not format the code correctly for HTML and therefore some of it is missing.
I'll modify it just for the records!
Ant.
|
|
|
|
|
Hi.
Everything is nice about what u said to me for reading and writing to files. Except one or two things.
Well first of all it cannot convert from objectA to char*.
That's why I didn't use this method before, because I couldn't handle this stuff.
Anyway why do u have to use binary files?
outfile.write ((char*)objectA, sizeof(objectA));
objectA(field by field) into the file test.txt.
Remember, the file contents are now binary.
So u may see many strange character when you open test.txt in a notepad.
THX
|
|
|
|
|
Ah. You've been told how to without any understanding of what's happening, which makes it difficult to fix this minor problem.
The line
outfile.write( (char*) objectA, sizeof(objectA));
should probably read
outfile.write( (char*)&objectA, sizeof(objectA));
as you need to specify the address.
Essentially, it's writing everything from memory to do with objectA's storage out to disk. This is not necessarily a good thing.
If objectA contains any pointers, or has other objects embedded within it, you may well be able to read objectA back some time later, but then not be able to use it.
Serialising an object is something that the object itself should know how to do, since it is possibly the only entity aware of all it's members. A blind write (and read) of the space occupied does not take into account the fact that the object may refer to other things, such as a char* member. In that case, the address in the char* member would be written out, and not the string it's pointing to1. When the object is later read back, the same address is assigned. Now if the memory map has changed significantly, it's possible that the address is not only not pointing to the right data, but it may in fact be pointing to unallocated or deallocated memory, which will cause an exception in your app.
Steve S
1Yes, I know it's not a proper string, it's only an illustration, so calm down...
|
|
|
|