if I have something like this:
class A: public Mother{
public:
A(B b){ b_pointer = &b; };
void update() override { int value = b_pointer->getSomething(); };
private:
B* b_pointer;
};
class B{
public:
void update(//parameters);
int getSomething();
};
then in another part of the program, let's say in the class C, both a B and A object are created.
B b_object;
b_object(//attributes of C needed as parameters);
A a_object(b_object);
so, will b_pointer refers to b_object?
if inside a method of A I use b_pointer->getSomething(); will it always refer to b_object?
because i need to update a_object making it knowing about b_object, but I can't write the void A::update() method like update(B& b) {b.doThings()} since A::update overrides a Mother method and in the class C i have a vector of Mothers* to be updated.
Related
So I've created a class that accepts another object as a reference. The problem is.. I would like to access some of the attributes from the object that is passing the object inside the objects being passed. I really just need two way communication between my objects and I'm not exactly sure of the best way to get this done.
class A {
private:
void someMethod();
public:
A();
};
class B {
protected:
char someAttribute;
A& a;
public:
B(A& a);
};
someMethod() {
char newAttribute = someAttribute;
}
I would like someMethod to have access to someAttribute. I'm not sure if this is even the right way to got about this problem. I'm passing the object into another object in the main function. I'm not sure how much would change if I instanced the class directly inside the the other class.
I also tried making A a child class but it didn't work and I think this would create two separate instances of the parent class which doesn't make any sense to me.
Then I tried using friend.
class A {
private:
void someMethod();
public:
A();
};
class B {
protected:
char someAttribute;
friend class A;
A& a;
public:
B(A& a);
};
someMethod() {
char newAttribute = someAttribute;
}
I'm not sure the right way to do it but the above code doesn't work.
If someone has a much better way of implementing this code, I'm all ears.
You could pass a reference (pointer):
class B;
class A {
private:
void someMethod();
B *b = nullptr;
public:
A();
void setRef(B &b) {this->b = &b;}
};
class B {
friend A;
protected:
char someAttribute;
A& a;
public:
B(A& a) : a(a) {this->a.setRef(*this);}
};
void A::someMethod() {
if (b)
char newAttribute = b->someAttribute;
}
If it becomes more complex you could use a weak_ptr
You can also do following way.If You are not bounded with other limitations.
Using forward declartion of class.
class B
{
protected:
char someAttribute;
public:
friend class A;
};
class A
{
private:
void someMethod(B b);
public:
};
void A::someMethod(B b)
{
char newAttribute = b.someAttribute;
}
class A {
private:
char a;
char sub_f(char *);
public:
A();
char f(char* ) {some actions using sub_f(char*);}
};
class B {
private:
char b;
public:
B();
void execute() { b = f("some text");} //PROBLEM IS HERE
}
Can smb explain me how can I call f(char *) function which is a member of class A, from the void B::execute() ? I can't compile it right now. If I make f(char*) a friend function of the class A, there is another problem appear :
friend f(char*) doesn't know anything about private function sub_f(char*) .
I am a beginner in C++ and will be appreciate for full answers with explanation.
If you have a public member function, like
class A {
public:
char f(char* );// {some actions using sub_f(char*);}
};
you can call it on an instance
A a;
char just_one_char = a.f("Whatever");
The same applies across the board - to call this member function you need an instance.
One approach would be to make your class B have a member variable of type A:
class B {
private:
char b;
a a;
public:
B();
void execute() { b = a.f("some text");} //PROBLEM Solved
};
If f doesn't need any instance data from class A it could be static, or a free function.
Perhaps there isn't a one-to-one relationship between B and A like this.
Perhaps execute could make an A when it needed to:
class B {
private:
char b;
public:
B();
void execute() {
A a;//just needed for this function call, rather than lifetime of B
b = a.f("some text"); //PROBLEM is solved a different way
}
};
So, I have an abstract class A, which I implement in B.
B uses C, and A cannot depend on C. so how do I set it?
I dont want to use a dynamic cast and add a setter to B.
class A
{
public:
virtual void doSomething() const = 0;
}
class C
{}
class B
{
public:
virtual void doSomething() const { mVar; }
private:
C mVar;
}
I have internal objects, which should'nt be used by client code :
class InternalA {};
class InternalB {};
I have public interface objects A, B, C. Internally, i need to construct objetcs InternalA from A and InternalB from B, but A and B can only be accessed by a pointer to base class C. I could use covariant virtual method but doing so, my Internals become public, and InternalA and InternalB are not really two subtytes of the same base class.
Or i could do something like that :
class C {
// some data
public:
C() {};
// some pure virtual methods and virtual methods
virtual C *getConcrete(void) const =0;
};
class B : C {
public:
//methods
virtual B *getConcrete(void) { return static_cast<B>(this); };
};
class A : C {
public:
//methods
virtual A *getConcrete(void) { return static_cast<A>(this); };
};
And then use an internal builder with polymorphic method in A or B parameter.
Edit :
To build InternalA and InternalB, i can use a function/method like that :
void somefunction(A *a) {
InternalA x(<using a->smthg>);
// do stuffs
};
void somefunction(B *b) {
InternalB x(using b->smthg>);
//do stuffs
};
What do you think about this hack ?
I think its impossible to solve this problem using only class C. To build InternalA or InternalB you need knowledge about A or B. At builder definition A or B must be defined. So I think you should use dynamic_cast. Or some kind of type id implemented by virtual functions if dynamic_cast is prohibited.
#include "A.h"
......
InternalA* buildInternalA(const C* c) {
const A* a = dynamic_cast<const A*>(c);
if (a)
return new InternalA(a);
return 0;
}
But where you use builder(in other cpp file), you don`t need definition of A and B, only declaration of builder:
class InternalA;
class C;
InternalA* buildInternalA(const C* c);
Suppose an object of class B is a member of class A.
class B{
//Definitions
}
class A{
public:
A();
B b_child;
int some_function();
}
One of the functions defined inside B needs to call a (public) function from its owner (parent?) A. Is there an immediate way to do this?
The only way I've managed to do this so far was to implement it outside the classes' definitions:
A a_obj;
a_obj.b_child.setowner(&aobj);
which tells b_child who is its owner. I don't like this. I'd rather use some builtin method for b_child to access its parent (if possible). If that's not possible, I'd rather pass the owner's address directly in the constructor for B, but I don't know how to reference A's address inside its definition.
There is no builtin method to get the 'owner' of a variable, whatever that means. Your approach of setting the owner is correct. Furthermore, doing so in the construction of B is also a correct decision. Sample code:
class B
{
public:
explicit B( A* owner ) : _owner( owner ) {}
...
private:
A* _owner;
};
class A
{
public:
A() : _child( this ) {}
...
private:
B _child;
};
Note some compilers may give you a warning for using this in that context, but its ok for the current example. Just make sure you don't call any A member functions from within B constructor, since the pointer you get still points to an unconstructed object at that stage.
I'd rather use some builtin method for b_child to access its parent (if possible).
No, it's not.
but I don't know how to reference A's address inside its definition.
You can use this pointer.
A() : b_child(this) { }
You should use this pointer to refer to the object within itself
class B{
//Definitions
}
class A{
private:
B b_child;
public:
A()
{
b_child.set_owner(this);
}
}
You should define B like the following:
template <class T, int N>
class B
{
public:
int example_func() { return static_cast<T&>(*this).some_function(); }
};
And then make B<A> a subclass of A (so it can call A directly).
class A : protected B<A,0>, protected B<A,1>
{
A();
int some_function() { return 42; }
};
This is called the curiously recurring template pattern.
If you don't want B to be a template class, and you're only going to use B with A, then the following is fine:
template <int N>
class B
{
public:
int example_func() { return static_cast<A&>(*this).some_function(); }
};
class A : protected B<0>, protected B<1>
{
A();
int some_function() { return 42; }
};
Alternatively, if you want to use B with not just A, but don't want to make B a template class (say, if you want a collection of pointers to B), you can do the following:
template <int N>
class B
{
public:
int example_func() { return some_function(); }
virtual int some_function() = 0;
};
class A : protected B<0>, protected B<1>
{
A();
int some_function() { return 42; }
};
This will resolve the some_function() call at run-time, and require a virtual pointer to be stored in your class.