C++ assigning an object to another class - c++

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

Related

C++ inheritance pattern

I am after your opinion on how best to implement an inheritance pattern in C++. I have two base classes, say
class fooBase{
protected:
barBase* b;
};
class barBase{};
where fooBase has a barBase. I intend to put these classes in a library, so that wherever I have a fooBase it can use its barBase member.
I now intend to create a specialisation of these in a specific program
class fooSpec : public fooBase{};
class barSpec : public barBase{};
Now I want fooSpec::b to point to a barSpec instead of a barBase. I know that I can just initialise b with a new barSpec, but this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
Is there another way that this is often acheived?
Cheers.
Create a method in your specclass to cast the b into the special version.
That way instead of casting it all the time, it looks like a getter.
On the other hand OO is about programming towards interfaces and not objects. So what you are doing here looks like programming towards objects. But the is difficult to see as this example is purely theoretical.
You may consider the template solution:
template <class T>
class fooBase{
protected:
T* b;
};
and then use it as
class fooSpec : public fooBase<barSpec>{};
while ordinarily, the base would be used as fooBase<barBase>.
Is this what you want?
Normally we create a function that has the cast and returns the pointer -- and use that instead of the member directly.
Now I want fooSpec::b to point to a barSpec instead of a barBase.
There's no such thing as fooSpec::b. b belongs to fooBase, and your new class fooSpec is a (specialization of) a fooBase. You can't change the fact that b, a fooBase member, is of type barBase. This is a property of all the instances of fooBase that you can't invalidate in the particular subset of instances concerned by your specialization.
I know that I can just initialise b with a new barSpec, but this would
require me to cast the pointer to a barSpec whenever I wanted to use
specific functions in the specialisation wouldn't it?
Yes and no. Yes, you need to do that cast; but no, you don't need to do it every time. You can encapsulated in a function of fooSpec.
Is there another way that this is often acheived?
Not that I'm aware of.
this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
That depends on whether the method you are trying to invoke is defined in the superclass and whether it is virtual.
You need to cast the pointer before invoking a method if one of the following is true...
The method belongs to the subclass only
The superclass has an implementation of the method and the subclass's implementation does not override the implementation in the superclass. This amounts to a question of whether the function is a virtual function.
Avoid data members in non-leaf classes, use pure virtual getters instead. If you follow this simple rule, your problem solves itself automatically.
This also makes most non-leaf classes automatically abstract, which may seem like an undue burden at first, but you get used to it and eventually realize it's a Good Thing.
Like most rules, this one is not absolute and needs to be broken now and then, but in general it's a good rule to follow. Give it a try.
If it looks too extreme, you may try one of the design patterns that deal with dual hierarchies such as Stairway to Heaven.

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)

Access derived class' functions through pointer (C++)

Here's an example of the situation:
CAnimal *poTest = new CDog();
When I write "poTest->" All I can see are functions from the base class (in example: CAnimal) and not the ones in the derived one. How can I access these?
You've declared poTest as a CAnimal.
So it makes sense that you'll only see what a CAnimal can see.
If you want to use methods that a CDog uses, declare it so.
CDog * test = new CDog();
test->someFunction();
CAnimal *poTest = new CDog();
static_cast<CDog *>(poTest)->someFunction();
I'm assuming CDog (what's with the C prefix btw) inherits CAnimal. The compiler cannot know that your poTest variable happens to be a CDog - it can only see that it is a CAnimal. So, you can't call a member function of CDog with a variable of type CAnimal * - you need to convert the pointer to a CDog *, this tells the compiler to "treat this as a CDog".
In general in such a case you should only be using the interface of the base class and that function wouldn't be accessible. If you're trying to use the derived interface, consider storing a pointer to CDog instead of CAnimal. Instead of trying to get to the child methods, make your parent interface appropriate.
If you really know that your pointer points to a dog you can downcast although this may be a design smell in some cases:
CDog* cdog = dynamic_cast<CDog *>(poTest); // Safer
if(cdog)
{
cdog->someFunction();
}
static_cast<CDog *>(poTest)->someFunction(); // Faster
Since you declare poTest being an CAnimal, you can just call functions defined in CAnimal. Usually this is enougth since the base class should expose the method needed as virtual functions, dealing with a CAnimal instance and having to cast a CDog usually signal that there is something to improve in the design.
dynamic_cast<CDog*>(poTest)->CDogSpecificFunction();
Either define it as a dog:
CDog *poTest = new CDog();
Or use a cast:
static_cast<CDog*>(poTest)->bark();
Or, as per some of the other answers use one of the other casting functions/operators. In general, however, making heavy use of casts is considered bad practice; this is one of the reasons why many mainstream languages offer generics (see e.g., here).

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

C++, statically detect base classes with differing addresses?

If I have a derived class with multiple bases, each this pointer for each base will be different from that of the derived object's this pointer, except for one. Given two types in an inheritance hierarchy, I'd like to detect at compile time whether they share the same this pointer. Something like this should work, but doesn't:
BOOST_STATIC_ASSERT(static_cast<Base1*>((Derived *)0xDEADBEEF) == (Derived*)0xDEADBEEF);
Because it needs to be an 'integral constant expression' and only integer casts are allowed in those according to the standard (which is stupid, because they only need compile time information if no virtual inheritance is being used). The same problem occurs trying to pass the results as integer template parameters.
The best I've been able to do is check at startup, but I need the information during compile (to get some deep template hackery to work).
I don't know how to check what you wan't but note that your assumption is false in presence of empty base classes. Any number of them can share the same offset from the start of the object, as long as they are of different type.
I am trying to solve this exact same issue. I have an implementation that works if you know what member variable is at the beginning of the base class's layout. E.g. if member variable "x" exists at the start of each class, then the following code will work to yield the byte offset of a particular base class layout from the derived class layout: offsetof(derived, base2::x).
In the case of:
struct base1 { char x[16]; };
struct base2 { int x; };
struct derived : public base1, public base2 { int x; };
static const int my_constant = offsetof(derived, base2::x);
The compiler will properly assign "16" to my_constant on my architecture (x86_64).
The difficulty is to get "16" when you don't know what member variable is at the start of a base class's layout.
I am not even sure that this offset is a constant in the first place. Do you have normative wording suggesting otherwise?
I'd agree that a non-const offset would be bloody hard to implement in the absence of virtual inheritance, and pointless to boot. That's besides the point.
Classes do not have a this pointer - instances of classes do, and it will be different for each instance, no matter how they are derived.
What about using
BOOST_STATIC_ASSERT(boost::is_convertible<Derived*,Base*>::value)
as documented in the following locations...
http://www.boost.org/doc/libs/1_39_0/doc/html/boost_staticassert.html
http://www.boost.org/doc/libs/1_38_0/libs/type_traits/doc/html/boost_typetraits/reference/is_convertible.html
I didn't realize that the compiler would insert this check at runtime, but your underlying assumption isn't entirely correct. Probably not in ways that you care about though: the compiler can use the Empty Base Class Optimization if you happen to inherit from more than one base class with sizeof(base class)==0. That would result in (base class *)(derived *)1==at least one other base class.
Like I said, this probably isn't something you would really need to care about.