Need Of DECLARE_DYNAMIC? - c++

DECLARE_DYNAMIC() is used for getting RTTI, when a class derived from CObject class, I know it.
But i saw in a code,a class derived from CPropertySheet have this MACRO.
-> what is the need of it, as neither iskindof() nor any other Run time information is used?
this derived class has two constructors , called via new when creating objects.
my question is What is the need of DECLARE_DYNAMIC() ,in this class ?

The use of this macro allows easy type checking in the MFC way. Assume you have a special CPropertyPage base class, Or you have a special derived CPropertySheet with a special interface named CMyClass you can easily do a cast with a type check with DYNAMIC_DOWNCAST.
So the fast answer is: If you want to use DYNAMIC_DOWNCAST or STATIC_DOWNCAST with the MFC type checking. It just allows the usage of IsKindOf.
It is the lowest form of the tripple DECLARE_DYNAMIC, DECLARE_DYNCREATE, DECLARE_SERIAL.
Also there are more answers on this here in stack overflow.

Related

c++ base class object to call unknown methods in subclasses

I am facing this problem:
An upstream application defines a class (e.g. box), and a member (say property) with a base class type. I would make a derived class for that member, add new members and methods without updating their application.
Essentially I do box->property = make_shared<myProperty>(). Is there a way to keep the interface of calling the members and methods the same? That is, to access a property using box->property->length or box->property->GetWeight(), rather than dynamic_pointer_cast<myProperty>(box->property)->GetWeight(). The challenge here is they won't update the base property class, and I am not supposed to change box. But we wish to keep the interface the same so our customers won't complain.
Is it possible? If not, how could we do to best keep the main app and my plugin relatively independent while minimize the changes on the customer side? Any suggestions are welcome.
Looks to me like the derived class for that member property violates Liskov's substitution principle.
You mentioned not being able to modify the Box class.
But are you allowed to modify the property base class? I suggest you add your "additional" methods of your derived class to the property base class.
The intent here being that the interface between the base and derived class should be one and the same. So do this only if it makes sense design wise.

C++ assigning an object to another class

I am trying to create a pointer to a class as follows.
ASTNode* pAssign = new ASTAssignmentNode();
However, pAssign does not consist of the variables defined in class ASTAssignmentNode . Am I missing out on something here? How can I access the variables defined in ASTAssignmentNode() ? ASTAssignmentNode() inherits from ASTStatementNode() which inherits from ASTNode().
When writing pAssign->variable (which is declared in ASTAssignmentNode()) an error occurs "pAssign does not contain definition for member variable"
I am not experienced in C++.
Would appreciate any help.
You should use ASTAssignmentNode* pAssign instead. If you're doing this for a class assignment and they give you files you aren't supposed to modify that make you utilize ASTNode*, ask your TA about it because I've been in that situation and there should be workarounds you can use but it will differ from different assignments.
Try casting to access variables belonging to ASTAssignmentNode class
((ASTAssignmentNode* ) pAssign)->variable
What I have used is called a regular cast. You may also use static cast or dynamic cast has mentioned by M.M. If you want a detailed breakdown of which type of cast you need, check out a post here.
As long as you are certain ASTAssignmentNode is a child of ASTNode there should be no implications.
When you cast ASTAssignmentNode to ASTNode it will only contain the class definition for ASTNode and it knows nothing about ASTAssignmentNode. That is why you need to cast it back.
An exception to this are virtual functions. Virtual functions call the child class implementation if they exist.
Since pAssign is a pointer to the base class, you will need to cast it to the derived class, ASTAssignmentNode. Preferably with a c++ dynamic_cast.
dynamic_cast<ASTAssignmentNode*>(pAssign)->variable

How to add a base class to a vector of derived classes

I have a std::vector that holds shared pointers to a derived class cDerivedClass, I also have shared pointers for the base class too. So something like this:
typedef SHARED_PTR<cBaseClass> cBaseClassPtr;
typedef SHARED_PTR<cDerivedClass> cDerivedClassPtr;
std::vector<cDerivedClassPtr> vDerivedPtrList;
Now if I want to have a CDerivedClass::AddComponent(cBaseClassPtr inpBaseClass) method that takes an argument of type cBaseClassPtr and adds it to the vector (vDerivedPtrList) of derived classes, how would I go about doing this?
I know dynamic_cast won't work since base-to-derived conversions are not allowed with dynamic casts unless the base class is polymorphic. I've tried static casting the cBaseClassPtr to a cDerivedClassPtr, but I'm thrown an error.
void cDerivedClass::AddComponent(cBaseClassPtr inpBaseClass)
{
MY_ASSERT(inpBaseClass, "Component cannot be NULL");
cDerivedClassPtr pDerviedPtrToAdd = static_cast<cDerivedClassPtr>(inpBaseClass);
this->mvComponentList.push_back(pDerviedPtrToAdd);
}
Edit: To be exact this is the error I'm getting:
No matching conversion of static_cast from 'cBaseClassPtr' (aka 'shared_ptr<cBaseClassPtr>') to 'cDerivedClassPtr' (aka 'shared_ptr<cDerivedClassPtr>');
I'm using boost's implementation of smart pointersboost::shared_ptr
If your CDerivedClass::AddComponent function can only really deal with cDerivedClassPtrs, then adjust its signature accordingly :
CDerivedClass::AddComponent(cDerivedClassPtr inpDerivedClass)
If it should be able to deal with cBaseClassPtr, then adjust the definition of vDerivedPtrList to hold cBaseClassPtrs :
std::vector<cBaseClassPtr> vBasePtrList;
It is difficult to know exactly what you are trying to do here, and what smart-pointer implementation you are using.
Why is your base class not polymorphic? If it were you could use some kind of double-dispatch to get it to add itself to an appropriate collection.
If there is a different vector for each derivation, then each derived class would know which one it is supposed to add itself to.
You will need your base class to derive from enable_shared_From_this so it can shared-pointer itself if it is already currently shared_ptred (which presumably it is): although that will shared_ptr itself into the base type you can then create another shared_ptr based on the life of the first and put that in the collection.
(That is assuming you are using boost and I think std has the same interface)

Using derived Class from CEdit in my DIalog

I'm doing an application using MFC. I just made a class that is derived from CEdit so I could intercept OnChar() and do data validation. How do I substitute the edit control in my application with the derived one I made?
Do NOT use GetDlgItem!!
GetDlgItem() returns a CWnd-pointer and nothing else. This means you have a sliced CMyCustomEdit pointer. Sure, it works in all cases where your method sends a message to the underlying HWND. But that's just pure luck! You can read more about the problem here.
The right solution is to subclass your edit control using DDX_Control.
I found the solution. The reason why I was having such a hard time is because I didn't use the Class Wizard to create the new class, making things very complicated. If you simply use the Class Wizard, you have the option to add control variables to your derived classes like if they were regular classes, as long as the base class is the right class for your element. This is not necessary though. All you have to do is create a pointer of the type of your derived class and cast the item you are trying to get, like you would normally do with a non-derived class.
Example of accessing an Edit Control using a class derived from CEdit
CMyCustomEdit * editPtr = (CMyCustomEdit*)GetDlgItem(IDC_EDIT1);
As mentioned below by another member (Thanks for that), using GetDlgItem is not a good idea. I actually, in my code, ended up Sub-Classing it so I could use my new class with my Edit Controls that already existed. As mentioned before, I did not understand that an Edit Control was not necessarily attached to CEdit, so the example above should give a clear idea that your IDC_EDIT can be used as CMyCustomEdit as well as a CWnd and so on; it will behave naturally as long as you reference it with the right classes.
Now for the Sub-Classing. If you actually want to make you Edit Control to always call your derived class before your base class, you will have to make it a Sub Class. Don't think of it as an Object Oriented concept, this is only so the messages (Like WN_CHAR) will go through your derived class first and then call the base class.
Example of Sub-Classing CMyCustomEdit on an Edit Control:
First you need to include the .h file of your new class in the .cpp and .h of your dialog box. Those are the ones that usually has the same name as your project. Here it will be MyMainDialog.
#include "CMyCustomEdit.h"
In the derived dialog class include a variable of the type of your new derived class:
class MyMainDialog : public CDialogEx
{
protected:
CMyCustomEdit m_cmCEdit;
}
Then in the OnInitDialog() of your derived dialog class (MyMainDialog) Sub-Class your edit control. For safety, add this after the regular code in the function and before the return (As usual):
m_cmCEdit.SubclassDlgItem(IDC_EDIT1, this);
After this is done, when you do anything in your Edit Control with the ID IDC_EDIT1, the messages will go trough CMyCustomEdit before going to CEdit. This usually is necessary when you need to overwrite messages from the base classes.
Hope it helps anyone with a similar question.

Is there a way to determine at runtime if an object can do a method in C++?

In Perl, there is a UNIVERSAL::can method you can call on any class or object to determine if it's able to do something:
sub FooBar::foo {}
print "Yup!\n" if FooBar->can('foo'); #prints "Yup!"
Say I have a base class pointer in C++ that can be any of a number of different derived classes, is there an easy way to accomplish something similar to this? I don't want to have to touch anything in the other derived classes, I can only change the area in the base class that calls the function, and the one derived class that supports it.
EDIT: Wait, this is obvious now (nevermind the question), I could just implement it in the base that returns a number representing UNIMPLEMENTED, then check that the return is not this when you call it. I'm not sure why I was thinking of things in such a complicated manner.
I was also thinking I would derive my class from another one that implemented foo then see if a dynamic cast to this class worked or not.
If you have a pointer or reference to a base class, you can use dynamic_cast to see which derived class it is (and therefore which derived class's methods it supports).
If you can add methods to the base class, you can add a virtual bool can_foo() {return false;} and override it in the subclass that has foo to return true.
C++ does not have built in run-time reflection. You are perfectly free to build your own reflection implementation into your class hierarchy. This usually involves a static map that gets populated with a list of names and functions. You have to manually register each function you want available, and have consistency as to the calling convention and function signature.
I believe the most-correct way would be to use the typeid<> operator and get a reference to the type_info object, and then you could compare that (== operator) to the desired type_info for the data types you wish to care about.
This doesn't give you method-level inspection, and does require that you've built with RTTI enabled (I believe that using typeid<> on an object that was built without RTTI results with "undefined" behavior), but there you are.
MSDN has an online reference to get you started : http://msdn.microsoft.com/en-us/library/b2ay8610%28VS.80%29.aspx