I am trying to make a call to a Parent class method from a contained object, but have no luck with the following code. What is the standard way to do it?
I have searched around and this seems to work for inherited objects, but not for contained objects. Is it right to call it a Parent class even? Or is it called an Owner class?
class Parent{
private:
Child mychild;
public:
void doSomething();
}
class Child{
public:
void doOtherThing();
}
void Child::doOtherThing(){
Parent::doSomething();
}
A contained object has no special access to the class that contains it, and in general does not know that it is contained. You need to pass a reference or a pointer to the containing class somehow - for example:
class Child{
public:
void doOtherThing( Parent & p );
};
void Child::doOtherThing( Parent & p ){
p.doSomething();
}
The child has no connection to the parent class at all. You'll have to pass 'this' down to the child (probably in the constructors) to make this work.
If the child needs to interact with the parent, then it will need a reference to that object; at present, the child has no notion of an owner.
Related
Okay, I tried to put my problem/question in one sentence in the title. I have the following code example:
class ParentClass
{
};
//#include "ParentClass_Header.h"
class SomeOtherClass
{
ParentClass* parent;
public:
virtual void func(ParentClass* parentclass) {
parent = parentclass;
}
};
class ChildClass : public ParentClass
{
public:
};
void SomeOtherClass::func(ChildClass* childclass)
{
}
Anyway, I have a ParentClass which I inherited to a ChildClass. Another (SomeOtherClass) class has to hold some information about the ChildClass (the pointer is needed in the function SomeOtherClass:func(...)).
The compiler says something like the ChildClass* cannot be converted in ParentClass*. I don't think it is possible to do this the way I am trying to do it. The other way would be to declare a ChildClass* child_ptr and assign it with child_ptr = this in any member function (of class ChildClass). But it would be nice to know if there is another, maybe more professional way.
Your declaration and definition of func are different, in the class declaration you give it an argument of ParentClass * whilst you define it with a ChildClass*. If you only want for it to take a ChildClass* as an argument then declare it as such, or vice-versa if you would like the function to take any derived ParentClass*.
I would say however judging by your naming of "Child" and "Parent" that the code seems confused with its aim. It is not normal that a child would be derived from a parent, instead you would expect the parent class to have some form of container that managed the children. In this case one should pass the parent in the constructor if the child needs to communicate backwards to the parent.
I couldn't think of a better wording for the title, so it is a little misleading, however, I am not talking about a child accessing its variables inherited from its parent, which is easy enough.
What I am talking about is this:
class Parent {
protected:
Parent *target;
int hp;
}
class Child : public Parent {
public:
void my_func();
}
void Child::my_func() {
target->hp -= 50;
}
However, if I try to compile this, it will complain about 'hp' being "private in this context". The problem is that the child is not attempting to access its own parent's variables, but some other class', which may or may not be a Child itself.
An object can access all the variables and methods (public, protected, or private) of another object (two separate instances in memory) that is of the same class, so I thought that it would work with this as well, as it inherits from the class whose variables it's attempting to access, but it seems I was incorrect in assuming so.
Any tips?
P.S. Not to be rude or anything, but I know that I can just create get() and set() methods, but I was hoping for a cleaner way.
Member functions of a particular class only have access to protected members of base classes that actually are base class subobjects of objects of their own class type (or more derived types).
Members of one class do not have access to protected members of other instances of that base class and so are also forbidden from accessing protected members through a reference or pointer to the base class type even if at runtime that pointer or reference might be to an object that is of the type of the class whose member function is attempting the access. Access control is enforced at compile time.
E.g.
class X
{
protected:
int z;
};
class Y : X
{
public:
int f( const Y& y )
{
return y.z; // OK
}
int g( const X& x )
{
return x.z; // Error, Y::g has no access to X::z
}
};
In your example, in the expression target->hp, the access to target is legal because you are accessing a member of the current object (which has the type of the class of which the function is a member, Child), but the access to the member hp is not legal because the type of target is not a pointer to Child, but a pointer to Parent.
This is so easy (meaning the apparent misunderstanding of the OP, is because people aren't taking the time to read the OP).
You simply make the child a friend of the parent's variable that you need to access.
Or, you can make the child a friend of the parent class.
That way any child has access to any parent's member variables, exactly the way you are expecting.
class Child;
class Parent {
protected:
Parent *target;
int hp;
friend void Child::my_func();
}
class Child : public Parent {
public:
void my_func();
}
void Child::my_func() {
target->hp -= 50;
}
The downside to this is that EVERY child can have access to the variables of EVERY parent. However, you must consider that in your case, the compiler cannot know that Parent *target is the same instance as the child. Given that you named it target, I would expect that having EVERY child have access to variables of EVERY parent is what you want.
Here's another possibility. Have everyone else use an interface to access the parent, and have only your child use the actual parent class. The result is the same though. Every child has access to every parents variables.
You're confusing class with instance.
The child has access to the same member variables of the base class that is of the same INSTANCE.
hmm, strange nobody mentioned this so far, but you could declare Child to be a friend of Parent (maybe because your code isn't very clear about what exactly you want to do here)
class Parent {
friend class Child;
protected:
int hp;
}
class Child {
public:
void my_func();
Parent *target;
}
this would allow access. alternatively you could write an accessor method that's public:
class Parent {
public:
get_hp(){return hp;}
protected:
int hp;
}
Try to change to this
Class Child : public Parent
It is likely that this is a duplicate question, but I haven't been able to find the best way to approach this problem.
I have a parent class, which creates an object, which has useful methods operating on that object. I then want to create a child class, which takes the object of the parent class by reference and has a bunch of other methods which operate on it.
I was wondering how best to approach this? Should I pass a pointer to an object of the parent class as the constructor of the child class?
What I would like to do :
class obj_parent{
initializes object
virtual void method_1
virtual void method_2
}
class operation: public obj_parent {
void opertation_method_1(*object)
void opertation_method_2(object)
}
Also what difference would it make if the parent class and the child class were templated?
Some references on the subject which I didn't find fully answered my question, but could be useful.
Pass an object to a class constructor
Passing object of a template class to constructor of another class
Ok, so the example below does exactly what you wanted to do: the child modifies an instance of a parent object through a reference. The parent holds a single int. Yes, in real life an object usually would have more than one member variable, but this is just an illustrative example.
class parentInt {
public:
int memberNumber;
parentInt(int number) {
memberNumber = number;
}
parentInt() {
memberNumber = 0;
}
};
class childInt : public parentInt {
public:
parentInt& mReferenceToParentObject;
childInt(parentInt& referenceToParentObject) :mReferenceToParentObject(referenceToParentObject) {}
void addOne() {
mReferenceToParentObject.memberNumber++;
}
void subtractOne() {
mReferenceToParentObject.memberNumber--;
}
};
int main()
{
parentInt p(5); //parent int is 5
childInt c(p); //child int is a reference to parent
c.addOne(); // parent's memberNumber is now 6 because the child modified the parent through the reference
c.subtractOne(); // parent's memberNumber is now 5 because the child modified the parent through the reference
}
If your doing this to solve a system of equations (not mentioned in the original question, see comments), replace memberNumber above with a vector of vectors to represent a 2D matrix and then change addOne to an algorithm like Gaussian Elimination to solve the system of equations.
I am having trouble with RobotControl class members. The UML specifies the relation between RobotControl’s position and RangeSensor as composition. Doesn't using pointers for them, make them aggregation? How should I declare - create these members with respect to UML, or has UML mistaken?
Pointers in C++ can be used for both aggregation and composition. The distinction is, as correctly noted by Douglas, whether the lifetime of the objects is interconnected. In other words: Is the child destroyed when the parent is destroyed? The answer Yes stands for composition, No for aggregation.
How do we distinguish these cases in a C++ code?
Pointers in C++ can mean the ownership of another (dynamically created) object, or just refer to an object owned by someone else. Let’s show the differences in examples. I’ll explain why pointers can be useful for each type of relationship.
Aggregation with a pointer
In this case, it is fine to only forward-declare the class Child before class Parent declaration and the child member can be set and re-set during the lifetime of the Parent.
class Child;
class Parent
{
public:
Parent(Child* ch) : child(ch) {}
Parent() : child(NULL) {}
void setChild(Child* ch) { child = ch; }
private:
Child* child;
};
Composition with a pointer
The longest example shows that we can dynamically create and destroy the child using a pointer. The child’s lifetime is strongly interconnected with the Parent. However, we can still swap children during the lifetime of the Parent thanks to pointers. This solution also allows to only forward-declare class Child in the header file unlike the alternative below.
// --- header file
class Child;
class Parent
{
public:
Parent();
~Parent();
void renewChild();
private:
Child* child;
};
// --- source file
#include "child.h"
Parent::Parent()
: child(new Child)
{
}
Parent::~Parent()
{
delete child;
}
void Parent::renewChild()
{
delete child;
child = new Child;
}
Disclaimer
This example is a subject to the Rule of three/five/zero. I am intentionally letting the implementation of missing recommended methods up to the user, keeping this answer dialect-agnostic and as simple as possible.
Composition without pointers
Instead of writing constructor and destructor manually, you can just declare child in the class declaration and let the compiler to do the construction and destruction for you. This is valid as long as the class Child’s constructor requires no parameters (otherwise you’d need to write class Parent’s constructor manually) and the class Child is fully declared before the declaration of class Parent.
#include "child.h"
class Parent
{
private:
Child child;
};
Aggregation without pointers
To be complete, the alternative to using pointers for aggregation is using a reference. However, this prevents swapping children during the lifetime of the Parent object.
class Child;
class Parent
{
public:
Parent(Child& ch) : child(ch) {}
private:
Child& child;
};
I have been trying to understand function pointers in C++ so that I can successfully use them in one of my projects. I am running into a logic problem though. Say we have two classes: a parent class and a child class which inherits the parent class.
class Parent{
...other stuff
void (Parent::*ptr2func) ();
...other stuff
};
Then we have a child class:
class Child : public Parent{
...other stuff
void afunc();
...other stuff
};
I wanted to connect the pointer of the parent class to the afunc() function of the child class. In the constructor of the child class is where I tried to do it like so:
Child::Child()
{
ptr2func = &Child::afunc;
}
This returned an expected error:
cannot convert void (Child::*)() to void (Parent::*)() in assignment.
I was afraid that such a thing would happen. But how do I get over this? Can't I link a function pointer to a member function of a parent class to a member function of the child class? As you can understand I am trying to achieve polymorphism through function pointers just for experimenting and without using virtual functions. I was lead to believe that this is possible. What is my mistake? Or is it just not possible?
A void (Parent::*)() takes an object of type Parent. The function Child::afunc requires an object of type Child. Converting the pointer to void (Parent::*)() would therefore allow for an invalid call.
Member function pointers can't really be used to implement polymorphism. The traditional way to implement polymorphism without using virtual is to use regular function pointers:
struct MyBaseClass
{
void (*function)(MyBaseClass* this_pointer);
};
It would be dangerous if that conversion worked as you would be able to call a function in class Child with a pointer or reference to a Parent which might not be of type Child.
If you are passing in a function and a pointer/reference you could use a boost::bind to achieve it.