Click here to Skip to main content
15,889,216 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have an inheritance question. Say I have two classes, one a base class and another a derived class. Both classes are MFC classes derived from CWnd, so I can use CRuntimeClass to know which class I am working with. What I need to know is if there is a way I can tell, from the base class, if the function I am in has been overridden in the derived class.

In my case I am looking at CWnd::OnContextMenu(). The documentation says that if you do not handle the message in your override you must call Default(), which is all that CWnd::OnContextMenu() does. How can I make the call to Default() be conditional on OnContextMenu() not being overridden?

Using CRuntimeClass I can check if the base class has been derived from, but how can I check if OnContextMenu() has been overridden?

class CBaseWnd : public CWnd
{
...
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point)
    {
        bool value = CallSomeFunction(pWnd, point); // may popup menu?

        if (false == value && !IsDerivedFunction())
        {
            Default();
        }

        SetReturnValue(value);
    }

    bool IsDerivedFunction()
    {
        CRuntimeClass* pRTC = GetRuntimeClass();
        // pRTC->m_lpszClassName will be "CDerivedWnd"
        //
        // How can I check for existance of CDerivedWnd::OnContextMenu
...
};


class CDerivedWnd : public CBaseWnd
{
...
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point)
    {
        CBaseWnd::OnContextMenu(pWnd, point);
        bool value = GetReturnValue();

        if (false == value)
        {
            value = CallSomeOtherFunction(pWnd, point); // may popup menu?
        }

        if (false == value)
        {
            Default();
        }
    }
};


I tried using macros by using the # stringizing operator and the ## tokenizing operator with no luck. Is this even possible or am I barking up the wrong tree so to speak?
Posted
Comments
Jochen Arndt 27-Nov-15 4:03am    
It seems that you think too complicated.

When the derived class implements OnContextMenu and does not call the base class version, that is never called. It is called when:
- There is no derived class.
- Derived class has no handler.
- Derived class has handler but calls base class version (does not perform any action).
In all of these cases do your work.

This is a common scenario. A derived class calls the base class version only when it does not handle the request itself.

Note also that I would not call Default() but the base class function instead.

1 solution

This would be a total abuse of object-oriented functionality. One of the major ideas behind OOP is making the use of instances of classes type-agnostic. For this purpose, the difference between the runtime types and compile-time types has been created. The compiler works with a variable of some type, which is a compile-time type, but this variable can be assigned to the object of some derived type, which will be the runtime type. The code using this instance remains unaware of actual type. It is compiled in the assumptions based on on the compile-time type, which server as a common interface for two or more derived types. Moreover, some of the functions called on this variable, directly or indirectly, can be overridden to achieve different behavior. They are dispatched dynamically, so a function defined in a base type will call some virtual method, but actual implementation dispatched to this inner call will depend on what runtime type is that.

Now, one of the main principle of object-oriented design is too keep agnostic code agnostic. Knowing the runtime type is never a goal. The real goal is to get some correct behavior. You need to design your class hierarchy, and, most importantly, the virtual functions, overridden or not, the way to achieve that functionality.

So, no positive advice for your — you went too far in wrong direction. I only can tell you what can help you. First of all, learning of OOP ideas and techniques. I hope your mistake can become be a good source of ideas and a good lesson to learn. But first of all, you need to realize what your problem really is. I can tell you what is it: you create your class hierarchy, virtual functions and overrides with the only purpose: to create something to struggle against, instead of helping to achieve your goals.

If you can formulate your real goal, we can consider concrete solutions. I'm afraid even that could be difficult for you. Please, you have to realize what is the concept of the "goal" in your case. You cannot say, for example, "I want to know the type", or "I want to override", or "I want to create a class which…". Those would be some possible tools for solving problems, but not the goals. In other words, you should clean up formulation of your problem from your present-day thinking on how it can be solved, present a clear problem. Care to try?

—SA
 
Share this answer
 
Comments
PJ Arends 27-Nov-15 10:28am    
This is not an answer to my question. I know my real goal, you do not. And I know of a work around. But the work around could be considered a little messy so I was looking for a more elegant, neater way of accomplishing my goal.

If you have an answer, great, I would love to hear it. If all you are going to do is tell me I do not know what I am doing, or I do not know what my goal is, then just do not reply. You do not know what my goal is, you do not know what I am doing.

I just want to know if this is possible, and if so how? That is it. Nothing more, nothing less.
Sergey Alexandrovich Kryukov 27-Nov-15 17:45pm    
If you did not share your real goal, this is your problem. I discuss what I really see, and perhaps not what you want to see. My goal is not to "answer your question", which might be incorrect, I am trying to help you. If you want the hear only what you want to hear, you are not open to help, sorry.

As to "do not reply", let me tell you that all members are equal. I thin I know what to reply to and what not. By getting membership and publishing your post you agree to get all kind of answers and comments. Thank you for your advice though, but in this case it does not sound convincing.

Now, as to "you don't know what I am doing". Let me remind you are the one that you asked for help. I remembered old anecdote:
A drunk man is getting into a taxi. Taxi driver:
— Where to, sir?
Passenger:
— None of your business, you swine.

If you need help, be so nice to explain what you are doing. Or not. :-)

Thank you.
—SA
PJ Arends 27-Nov-15 19:52pm    
Seriously? I did not post this question in order to get into a debate with you. All I want is an answer to the question: "Is it possible to tell from a base class function if the said function has been overridden in a derived class? And if so, how?"

Simple. If you know the answer then I will really appreciate it. If you can say with certainty that it is not possible, then I will appreciate that answer also. Just do not try to tell me about OOP and how to do this or that or the next thing.

I am not new to this game. I am just trying to do something I have never done before, because it is unconventional, and was wondering if anyone had actually done it before and could help me.
Sergey Alexandrovich Kryukov 27-Nov-15 20:16pm    
I know, I know. Sorry for not answering. I do appreciate the level of sophistication you are going in, but...

This is just not interesting to me, by the reasons I explained. If you don't want to use my advice, don't. What's the problem?

I can understand you. You might be proud of your understanding of technology or other things, and can be irritated bu the fact that someone is teaching your the elementary things. But you also should understand that someone who answers your question is not familiar with you and your level of understanding. People are essentially equal; and past virtues don't really count. If you understand these things well, it's good for you, if not, listen for the advice, and take it critically. Why not taking it easy? (I can guess why.)

Why not talking with people with some understanding? You say "I did not post this question in order to get into a debate with you". It might be important for you, but not for others. You are claiming it and still continuing the debate. Why? And so on... I don't mind debates, so I'm not saying such things, otherwise I would simply stop discussing it.

—SA
Sergey Alexandrovich Kryukov 27-Nov-15 20:23pm    
All, right, on second thought:

I can see some absurdity in your problem. As I can see, you want to calculate if the function is overridden in the same function. And you call Default or not also in the same context. By you always know if the function is overridden in the present class, because this is where you define its implementation. The behavior of this function is fully defined by this implementation. In other words, its behavior cannot be modified by the function overridden in some other class. So, there is no situation where you need to know it.

Did I answer your question?

Besides, I doubt that documentation tells you "if you do not handle the message in your override you must call Default()". Default is used to call default implementation. You decide to call it or not in the same context where you modify the behavior. Do you copy?

—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900