 |
 |
Apologies for the shouting but this is important.
When answering a question please:
- Read the question carefully
- Understand that English isn't everyone's first language so be lenient of bad spelling and grammar
- If a question is poorly phrased then either ask for clarification, ignore it, or mark it down. Insults are not welcome
- If the question is inappropriate then click the 'vote to remove message' button
Insults, slap-downs and sarcasm aren't welcome. Let's work to help developers, not make them feel stupid.
cheers,
Chris Maunder
The Code Project Co-founder
Microsoft C++ MVP
|
|
|
|
 |
For those new to message boards please try to follow a few simple rules when posting your question.- Choose the correct forum for your message. Posting a VB.NET question in the C++ forum will end in tears.
- Be specific! Don't ask "can someone send me the code to create an application that does 'X'. Pinpoint exactly what it is you need help with.
- Keep the subject line brief, but descriptive. eg "File Serialization problem"
- Keep the question as brief as possible. If you have to include code, include the smallest snippet of code you can.
- Be careful when including code that you haven't made a typo. Typing mistakes can become the focal point instead of the actual question you asked.
- Do not remove or empty a message if others have replied. Keep the thread intact and available for others to search and read. If your problem was answered then edit your message and add "[Solved]" to the subject line of the original post, and cast an approval vote to the one or several answers that really helped you.
- If you are posting source code with your question, place it inside <pre></pre> tags. We advise you also check the "Encode HTML tags when pasting" checkbox before pasting anything inside the PRE block, and make sure "Ignore HTML tags in this message" check box is unchecked.
- Be courteous and DON'T SHOUT. Everyone here helps because they enjoy helping others, not because it's their job.
- Please do not post links to your question in one forum from another, unrelated forum (such as the lounge). It will be deleted.
- Do not be abusive, offensive, inappropriate or harass anyone on the boards. Doing so will get you kicked off and banned. Play nice.
- If you have a school or university assignment, assume that your teacher or lecturer is also reading these forums.
- No advertising or soliciting.
- We reserve the right to move your posts to a more appropriate forum or to delete anything deemed inappropriate or illegal.
cheers,
Chris Maunder
The Code Project Co-founder
Microsoft C++ MVP
|
|
|
|
 |
I have a straight class hierarchy.
The base class only has a method F() which calls another method P().
This method P() has to be implemented in all of the child classes and is called by polymorphism.
How can I get sure (at compile time) that all child classes implement this method P()?
class CBase
{
private:
virtual void P() { printf("CBase::P\n"); }
public:
void F() { printf("Base: F()->P(): "), P(); }
};
class C1 : public CBase
{
private:
virtual void P() override { printf("C1::P\n"); }
};
class C2 : public C1
{
private:
virtual void P() override { printf("C2::P\n"); }
};
void main()
{
CBase* p = new CBase();
p->F();
p = new C1();
p->F();
p = new C2();
p->F();
}
The above is the structure, when all is correct and will result in:
Base: F()->P(): CBase::P
Base: F()->P(): C1::P
Base: F()->P(): C2::P
Now I made a mistake and forgot to implement P() in class C1
class C1 : public CBase
{
private:
};
the compiler doesn´t error and it will result in
Base: F()->P(): CBase::P
Base: F()->P(): CBase::P
Base: F()->P(): C2::P
The only Idea is to use an Interface declaring P() abstract.
But since C2 is derived from C1 from CBase how to do?
Followeing code will show up an error on missing P(), but also shows up warnings when all is correct:
warning C4584: 'C1': base class 'PI' is already base of 'CBase'
warning C4584: 'C2': base class 'PI' is already base of 'C1'
struct PI
{
virtual void P() abstract;
};
class CBase : public PI
{
private:
virtual void P() { printf("CBase::P\n"); }
public:
void F() { printf("Base: F()->P(): "), P(); }
};
class C1 : public CBase, public PI
{
private:
virtual void P() override { printf("C1::P\n"); }
};
class C2 : public C1, public PI
{
private:
virtual void P() override { printf("C2::P\n"); }
};
also it doesnt help at all because now I have to be sure to derive C1,C2, ... from PI too, not only from its parent
So what I need is "method P() has to be declared in all child classes!- error if it is not"
|
|
|
|
 |
If you make P a pure virtual function, then the compiler will spot if it has not been implemented:
virtual void P() = 0;
|
|
|
|
 |
in which class, where to put this?
in CBase? -> then CBase doesnt have its P() method itself
in struct PI? ->still used this
"=0" is same systax like "abstract"
|
|
|
|
 |
You put it in the CBase class then every class that inherits CBase must implement P.
|
|
|
|
 |
does not work ...
I can ommit P() in C2 without compile error because its stil defined in C1
also I miss the code of CBase::P() itself
like:
class CBase
{
private:
virtual void P() abstract; public:
void F() { printf("Base: F()->P(): "), P(); }
};
class C1 : public CBase
{
private:
void P() override { printf("C1::P\n"); }
};
class C2 : public C1
{
private:
};
|
|
|
|
 |
The function C1::P() is declared private so it is not accessible in class C2. However, it is difficult to see exactly what problem you are trying to solve here.
|
|
|
|
 |
The structure is:
CBase <- C1 <- C2 <- ... etc
so straigt inheritance
CBase contains the main method CBase::F() which does all calculations needed.
And this method F() calls P() which should be choosen by inheritance (polymorphism)
CBase::F() { ...; P(); ... }
If I have CBase* b = new C2() than C2::P() will be called.
If I have CBase* b = new C1() than C1::P() will be called.
because of P() is a virtual method, overridden by C1::P().. C2::P() etc
now I miss C1::P() (forgot to add it) =>
if CBase b=new C1() then CBase::F() will call CBase::P() instead of C1::P() because there is no C1::P()
the override clause also tells the compiler to check if C1::P(), C2::P() match their parents P().
All is cointained by a complex chaotic SW-project which I will clean by small steps.
The idea behind:
P() is a call to a factory class which creates objects dependend on parameters AND on the class from which is called
CBase::P(int type) creates objects of CPbase_ so CPbase_1, CPbase_2...
C1::P(int type) creates obejcts of CP1_ so CP1_1, CP1_2...
C2::P(int type) creates obejcts of CP2_ so CP2_1, CP2_2...
etc...
CBase::F(switch,type) : if (switch) P(type) else CBase::P(type) ...
So if switch is set call the factory "of the class", else call the factory of CBase
example:
Cbase b = new C1();
b->F(true, 3) will create an object of C1_3()
All the pointers are stored in a list and for each element in the list the creation-funbtion F() is called
list ... C1*,CBase*,C3* etc ...
foreach element in list , element->F(switch,type) ...
|
|
|
|
 |
Hi
I have a CrichEditCtrl that works fine. However when the user Selects to view some other data in a Different Cdialog/CRichEditctrl. The first stops working and returns a zero
I display the Text I am Searching for and the Returned code From FindText (in the caption bar)
The Text looks fine However as soon as The Second Cdialog/RichEdit are created the return from the First CDaliog/RichEdit returns a zero
I double checked things as resource id of both RicheditCtrl's and they are different
|
|
|
|
 |
Are you saying both dialogs are open at the same time?
|
|
|
|
 |
Yes Actually this is the 3rd CDialog/CRicheditCtrl Pair That I have in my application The parent window is the First Cdialog/CrichEditCtrl. However After this is Created the Find functionality of the Richedit which is a child control of my main (for lack of a better term)CDialog stops working
|
|
|
|
 |
Without a lot more detail, including the code, it is anyone's guess. However using dialogs to open other dialogs does not sound like the best design.
|
|
|
|
 |
I get this message all of the sudden while I have a modless Cdialog and Richedit displayed
When I switch the debugger to threads I see a number of ntdll.dll worker threads
Can somebody point me in the right path
Thanks
|
|
|
|
 |
Just look at the Call Stack and find in this list your own (last called) module. Click on it to see what was your command/operation that caused the exception
|
|
|
|
 |
I did that went to the main thread (and looked at the stack) it pointed to thrdcore.cpp
!::GetMessage(&(pState->m_msgcur line 155 Please note I have created 5 other Threads 4 UI threads which act as a wrappers for my Derived CAsynSocket Class and a regular worker thread
Thanks
|
|
|
|
 |
Access violation means that you're accessing memory that hasn't been allocated to your application ... so do the obvious.
Go back a few steps on the stack and look at the sequence and look at all the pointer use and check
1.) The pointer is valid
2.) Is what it pointing at allocated
3.) If it is required that the structure it points to #0 terminated ... is it.
Something in the last calls is failing one of those criteria, if need separate every pointer to a temp line of code in those sections and run a debug test on it.
In vino veritas
|
|
|
|
 |
Without some more information about where this happened, the code that caused it, and the values of the variables involved, it is impossible even to make any suggestions. The only thing one can say is that you are using either an uninitialised variable, or one that has received an invalid value.
|
|
|
|
 |
The strange thing Is there all these worker threads (ntdll.dll) that seem to have come up okay
Thanks
|
|
|
|
 |
ForNow wrote: all these worker threads (ntdll.dll) that seem to have come up okay But that does not mean anything. The only way to solve this sort of problem is by tracking back to the point where the fault is created. This may be a simple bug in your code, cross-thread corruption, or any one of a million other things happening.
|
|
|
|
 |
If I put these two functions in a Windows program
/*-----*/
void SetTitle(HWND wn,char*S)
{SendMessage(wn,WM_SETTEXT,0,(long)S);}
/*-----*/
void GetTitle(HWND wn,char*S,long n)
{SendMessage(wn,WM_GETTEXT,n,(long)S);}
/*-----*/
these functions will set and read the window's title.
If I use these to catch the mouse interrupts:-
case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN: case WM_MBUTTONUP:
case WM_MBUTTONDBLCLK: case WM_MOUSEMOVE:
{int x=short(L&0xffff),y=short(L>>16)&0xffff; char Z[64];
sprintf(Z,"{%d,%d,%2x}",x,y,S); SetTitle(wn,Z); goto DEF;}
the window's title will show the current mouse return values.
Please, what are the message names used to catch interrupts from a game-type joystick?, if I want to program for a joystick or similar.
|
|
|
|
|
 |
The Windows functions still faithfully keep a return code (MK_MBUTTON = 16) for if the middle mouse button is down. Can computer mice with 3 buttons still be bought? Or have they gone where the passenger pigeon went?
|
|
|
|
 |
This is hardly a question for a C++ forum? You can find different mouse types in any PC store.
|
|
|
|
 |
Many mice have a scroll wheel which is also the middle button. If you have such a mice, just try to press the wheel instead of scrolling it.
So only the simplest / cheapest mice have only two buttons. Many even have more than three buttons nowadays.
|
|
|
|