|
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...
|
|
|
|
|
Thanx steve for pointing out my error , i wrote that reply in a hurry.
I'll make no such mistakes in future.;)
Remember... testing & debugging are always part of programming ...so exterminate those stinking bugs
|
|
|
|
|
dairiseky wrote:
Anyway why do u have to use binary files?
See if these help:
http://www.felgall.com/cplus4.htm
http://www.techtv.com/screensavers/answerstips/story/0,24330,3373133,00.html
http://forums.devshed.com/archive/t-105787
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
ok got y. thx again.
Though u didn't say to me what u meant by the lenght of a line. Does space and zero count in this lenght? i'm talking about the seekg().
Is this seekg() givin' me the possibility to read only a certain length of the file?
THX
|
|
|
|
|
dairiseky wrote:
Is this seekg() givin' me the possibility to read only a certain length of the file?
I'm not exactly sure what you are asking here, but seekg() can be used to get a file's length.
file.seekg(0, ios::end);
long filesize = file.tellg();
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
Sorry! my mistake. Thanks a lot to Steve for clearing the doubts.
You need not even include the (char*) part in read and write functions.
Only outfile.write (&objectA, sizeof(objectA)); should also work.
Keep in ur mind the things told by Steve about Pointers.
Avoid including pointers in classes that you have to write to the disk. But as far as simple data types and arrays are concerned, it would do just fine.
I hope that you know by now "why binary?"
Sorry again for the mistake on my part. thx steve
Remember... testing & debugging are always part of programming ...so exterminate those stinking bugs
|
|
|
|