I am working on an SDI project where the View inherits CFormView. I am trying to override CView::OnUpdate, but the compiler complains like so:
'CMyFormView::OnUpdate' : 'virtual' storage-class specifier illegal on function
definition
Here's my class definition:
class CMyFormView : public CFormView
{
…
// Overrides
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnInitialUpdate(); // called first time after construct
virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
};
The function I'm trying to override looks like this:
virtual void CMyFormView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
CFormView::OnUpdate(pSender, lHint, pHint);
//Get the current data from our document
CMyAppDoc* pDoc = GetDocument();
}
Could someone please tell me how to fix this?
Don't put "virtual" in the function definition (the .cpp file). You can put it only in the declaration (.h file). If it is already declared virtual in the base class hierarchy (CView?), then you don't need the "virtual" keyword at all since it will automatically be virtual if you have the same function declaration.
Related
in my mfc souce code, there are some classes, which are multi-inheritance. Like:
class CGraphComboBox:public CComboBox, public virtual CGraphBaseClass
class CGraphFrame:public CFrameWnd, public virtual CGraphBaseClass
class CGraphPanel:public CWnd, public virtual CGraphBaseClass
class CGraphBaseClass is like:
class CGraphBaseClass
{
public:
typedef int(*BaseClassWndCallbackFunc)(CGraphBaseClass* base_class, void* param);
public:
CGraphBaseClass(){};
virtual CGraphWnd* get_main_graph_window();
virtual void AppendMenuItems(CMenu* menu){};
void EnumerateParentWindows(BaseClassWndCallbackFunc enum_func, void* user_data);
};
One of their base class is MFC standard classes which I cannot modify(eg. CComboBox), another base class(CGraphBaseClass) is my own class.
The reason I make class CGraphBaseClass as virtual, is because in other location, I need to dynamic bind its functions.
like below code:
int AppendMenuForAllParents(CGraphBaseClass* base_class, void* param)
{
CMenu* menu = reinterpret_cast<CMenu*>(param);
base_class->AppendMenuItems(menu);
return 0;
}
in these classes, eg.CGraphPanel, there are some MESSAGE_MAP. eg:
BEGIN_MESSAGE_MAP(CGraphPanel, CWnd)
//{{AFX_MSG_MAP(CGraphPanel)
ON_WM_PAINT()//C4407
ON_WM_CREATE() //C4407
ON_WM_MOUSEMOVE()//C4407
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
because classes' multi-inheritance and virtual base class, there will be
warning C4407:cast between different pointer to member representations, compiler may generate incorrect code
in these message map.
meanings
#define ON_WM_CREATE() \
{ WM_CREATE, 0, 0, 0, AfxSig_is, \
(AFX_PMSG) (AFX_PMSGW) \
(static_cast< int (AFX_MSG_CALL CWnd::*)(LPCREATESTRUCT) > ( &ThisClass :: OnCreate)) },
would not generate the correct code.
My question is: how could I refactor the code, to avoid these multi-inheritance?
I want simulated interface sterotype in C++ using abstract class. But in Eclipse IDE I get "Multiple markers at this line
- The type 'Handler' must implement the inherited pure virtual method
'Handler::setNext'"
My question is Why this?.
Handler.h
class Handler {
public:
virtual void setNext(Handler &next) = 0;
Handler();
virtual ~Handler();
virtual void process() = 0;
public:
Handler *nextInChain;
};
Handler.cpp
#include "Handler.h"
Handler::Handler(){
}
Handler::~Handler(){
}
Oracle.h
#include "Handler.h"
class Oracle : virtual public Handler {
public:
Oracle();
virtual ~Oracle();
virtual void process();
virtual void setNext(Handler &next);
private:
};
Oracle.cpp
#include "Oracle.h"
Oracle::Oracle(){
Handler AQUI;//AQUI I get Multiple markers at this line
//- The type 'Handler' must implement the inherited pure virtual method
//'Handler::setNext'
}
Oracle::~Oracle(){
}
void Oracle::process(){
}
void Oracle::setNext(Handler &next){
}
This is incorrect:
Handler AQUI;
You cannot instantiate an abstract class.
What you want to do is define a pointer to Handler and assign it the address of a valid object from a child class, like Oracle.
I used to add "afx_msg" prefix at declaration of message handler function.
But I found the function still called whithout the prefix.
Is "afx_msg" nessary?
Added:
class CVLManageDlg : public CDialog
{ ...
protected:
void OnAdd();
void OnModify();
void OnDel();
}
BEGIN_MESSAGE_MAP(CVLManageDlg, CDialog)
ON_BN_CLICKED(IDC_ADD_VL_MANAGE, OnAdd)
ON_BN_CLICKED(IDC_MD_VL_MANAGE, OnModify)
ON_BN_CLICKED(IDC_DEL_VL_MANAGE, OnDel)
ON_NOTIFY(NM_CLICK, IDC_LIST_VL_MANAGE, OnClickList)
ON_WM_SIZE()
END_MESSAGE_MAP()
void CVLManageDlg::OnAdd()
{...}
void CVLManageDlg::OnModify()
{...}
void CVLManageDlg::OnDel()
{...}
ClassWizard requires that you use the afx_msg keyword in your message map handler declarations.
And this
I have the following abstract base class, SettingsInterface, that I use as an interface:
class SettingsInterface
{
public:
virtual void Refresh() = 0;
virtual void Update() = 0;
virtual void OnConnect() = 0;
virtual void OnDisconnect() = 0;
};
I'm trying to implement this interface in my class below, which inherits from TFrame. TFrame inherits from another class that also has a virtual method called Update.
class DebugSettingsFrame : public TFrame, public SettingsInterface
{
//a bunch of IDE-managed components - left out for brevity
public:
virtual void Refresh();
virtual void Update();
virtual void OnConnect();
virtual void OnDisconnect();
};
When I compile this, I get the error virtual function DebugSettingsFrame::Update() conflicts with base class 'TWinControl'.
I'm stomped on this. How can I resolve this without changing my interface's method definition, Update, to something else?
Edit - Follow-up:
So C++ doesn't have a construct similar to C# where you can explicitly implement interface methods that have the same definition?
Thanks!
Try something like (from the code I can't say exactly):
DebugSettingsFrame::TFrame::Update();
:: is the scope resolution operator. You should be able to specify precisely which version of the function you are calling.
However, note that this is a symptom of a design that may be getting too complex.
Here is the way I have my base class working:
class AguiWidgetBase
{
//variables
AguiDockingEnum dockingStyle;
std::string text;
AguiRectangle clientRectangle;
AguiColor tintColor;
AguiColor fontColor;
std::map<int,int,CmpIntInt> children;
//private methods
void zeroMemory();
virtual void onPaint();
virtual void onAddChildControl(AguiWidgetBase *control);
virtual void onTintColorChanged(AguiColor color);
virtual void onDockingStyleChanged(AguiDockingEnum style);
virtual void onTextChanged(std::string text);
virtual void onThemeChanged(const AguiTheme &theme);
void (*onPaintCallback)(AguiRectangle clientRect);
void (*onTintColorChangedCallback)();
void (*onDockingStyleChangedCallback)();
void (*onTextChangedCallback)();
void (*onThemeChangedCallback)();
protected:
AguiWidgetBase *parentWidget;
public:
AguiWidgetBase(void);
~AguiWidgetBase(void);
void addChildControl(AguiWidgetBase *control);
void removeChildControl(AguiWidgetBase *control);
AguiWidgetBase* getParent();
void paint();
void setTintColor(AguiColor color);
AguiColor getTintColor();
void setDockingStyle(AguiDockingEnum style);
AguiDockingEnum getDockingStyle();
void setText(std::string text);
std::string getText();
void SetTheme( const AguiTheme &theme);
};
Some of them work like this. There is a regular non-overridable funcion which calls the virtual function and the function pointer if its not NULL.
Will my virtual functions be able to once again go into the private scope when I create derived classes or must they be public?
I want to avoid them being public due to my design.
Thanks
Virtual functions can have public, protected, or private access.
A discussion of them via the C++ FAQ.
Should I use protected virtuals instead of public virtuals?
When should someone use private virtuals?
They can be private and do not need to be public.
Though they can be public, it is not considered as good design principle as Herb Sutter says.
virtual functions can be private. This is because private means that the function cannot be called by derived classes. It does not prevent the entry to the v-table being overwritten. This means that the both the base class and the derived class will have access to the overwritten virtual function.