sending data from one field of a class back to the class - c++

I have one class "A" that contains some field, one of these fiels is a class "Z", so I want to send data from this field(which is a class) to the class "A", when I tried to send data from the class "A" to the "Z" via reference it worked, but now I can't see how can I process data in the reverse way.
here's the code:
#ifndef SCREEN_AGENDAVIEW_HPP
#define SCREEN_AGENDAVIEW_HPP
#include <gui_generated/screen_agenda_screen/Screen_agendaViewBase.hpp>
#include <gui/screen_agenda_screen/Screen_agendaPresenter.hpp>
#include <string>
class Screen_agendaView : public Screen_agendaViewBase
{
public:
Screen_agendaView();
virtual ~Screen_agendaView() {}
void Open_Container()override;
void SendToView(std::string text);
protected:
CustomContainer_event ce;
};
#endif // SCREEN_AGENDAVIEW_HPP
#include <gui/screen_agenda_screen/Screen_agendaView.hpp>
Screen_agendaView::Screen_agendaView():ce(*this)
{
}
void Screen_agendaView::Open_Container()
{
customContainer_event1.setVisible(true);
customContainer_event1.invalidate();
}
void Screen_agendaView::SendToView(std::string text)
{
Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%s", text);
textArea1.setWildcard(textArea1Buffer);
textArea1.invalidate();
}
#ifndef CUSTOMCONTAINER_EVENT_HPP
#define CUSTOMCONTAINER_EVENT_HPP
#include <gui_generated/containers/CustomContainer_eventBase.hpp>
#include <gui/screen_agenda_screen/Screen_agendaView.hpp>
#include <string>
class CustomContainer_event : public CustomContainer_eventBase
{
public:
//CustomContainer_event();
CustomContainer_event(Screen_agendaView& d);
virtual ~CustomContainer_event() {}
virtual void initialize();
void Save_Note()override;
protected:
int pos_cursor = 0, shif = 1;
Screen_agendaView& s;
std::string text;
};
#endif // CUSTOMCONTAINER_EVENT_HPP
CustomContainer_event::CustomContainer_event(Screen_agendaView& s):s(s)
{
}
void CustomContainer_event::initialize()
{
CustomContainer_eventBase::initialize();
flexButton_Shift.setPressed(true);
}
void CustomContainer_event::Save_Note()
{
for (int i = 0; i <= pos_cursor; i++)
text += textArea2Buffer[i];
s.SendToView(text);
}

OP could pass class A's this (as pointer) or *this (as reference) to the constructor of the member var. of type class Z. Hence, class Z could store this pointer or reference as member itself and use it for accessing its "parent" class A instance.
Demo:
#include <iostream>
struct A; // forward declaration
struct Z {
A &a; // Z holds a reference to the associated instance of A
Z(A &a): a(a) { } // the associated instance of A is passed in constructor
void call(); // cannot be implemented before A became a complete type
};
struct A {
Z z; // A has a member var. of `struct Z` to which it will be associated
A(): z(*this) { } // A passes *this (the reference of its own) to z
void callZ()
{
std::cout << "A::callZ() called.\n";
z.call();
}
void call()
{
std::cout << "A::call() called.\n";
}
};
// now A is complete and Z::call() can use it to access (public) members of A &a
void Z::call()
{
std::cout << "Z::call() called.\n";
a.call();
}
int main()
{
A a;
a.callZ();
}
Output:
A::callZ() called.
Z::call() called.
A::call() called.
Live Demo on coliru
A class which stores a reference to another instance doesn't come without dangers. When such relations are designed then the (human) author should have the intended life-times in mind.
In this case, struct Z will be used as member of struct A exclusively. So, the associated instance of A will outlive it's member z.
If an instance of a class stores the reference to another instance which is destroyed before the first then the reference (inside the first) becomes dangling (i.e. referencing something which isn't existing anymore). As long as the reference isn't used nothing bad will happen. But accessing the dangling reference is Undefined Behavior. (It could crash or cause strange effects or (most accidental case) seem to work until something strange happens later.)
Example for wrong usage:
int main()
{
A *pA = new A();
Z z(*pA);
z.call(); // That's OK.
delete pA;
z.call(); // :-O BAD! z will call z.a.call() although z.a became dangling!
}
This design may cause an additional issue because struct A has to know struct Z to access its members and struct Z has to know struct A. That's a hen-egg-problem and C++ isn't the only effected language.
The solution is a forward declaration, in the above sample
struct A; // forward declaration
A forward declaration forms an incomplete type. It can be used to declare pointers and references. Pointers and references of incomplete types may be used only with certain constraints. E.g. sizeof of the pointer to an incomplete type is allowed because it actually doesn't depend on the type itself. (Pointers have always the same size.) In opposition, accessing the pointee of an incomplete type is not possible (as the pointee is of incomplete type and its contents simply not known as long as the type is incomplete).
Circular dependencies may require that declaration and definition of member functions are separated. In the above sample, it is remarked for Z::call():
// now A is complete and Z::call() can use it to access (public) members of A &a
void Z::call()
{
std::cout << "Z::call() called.\n";
a.call();
}
Defining classes in headers (as it is usual in C++ projects) may cause the issue of circular header dependencies.
If a.h declares struct A and z.h declares struct Z one might be attempted to #include "z.h" in a.h as well as #include "a.h" in z.h. This doesn't work. Either this will lead to a recursion or the author was clever enough to use header guards (to prevent duplicated definitions). In the latter case, one of the two involved headers will finally try to use the declaration of the other class in its own declaration and fail.
The solution is again a forward declaration of one involved class in the header of the other instead of the resp. #include. Both C++ sources may then include both header files without harm and provide the implementations which are based on both classes. This will, of course, require that the implementation of the resp. methods isn't done inline but separately done in the C++ source.

Related

Globally called constructor of a class template that adds this pointer to static list causes error

I have a class template that keeps track of all instances of a specific instance of the class template with a list of pointers. In the constructor, I push_back(this) to add the created instance to the class. If I create an instance within main, it works fine. But if I create a global instance, the constructor causes an error. The error is from the list.push_back() and it says that the insertion iterator is out of range of the container. I have recreated the bug with minimal code.
Header file
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
#include <list>
template<typename T>
class A
{
public:
static std::list<A<T>*> l;
A( T t ) : val( t ) { l.push_back( this ); }
~A() { l.remove( this ); }
T val;
void print() { std::cout << val; }
};
template<typename T>
std::list<A<T>*> A<T>::l;
#endif
Source file
#include "Header.h"
A<int> temp( 0 );
void main()
{
temp.print();
char c;
std::cin >> c;
}
I'm guessing it has something to do with the constructor call order, but does anyone know how to fix this?
Static members of template class specializations have unordered dynamic initialization, meaning that there is no guarantee in what order they will be initialized relative to other dynamic initialization.
If A<int>::l is initialized after temp, then initialization of temp will try to access A<int>::l before its lifetime began, causing undefined behavior.
The usual solution to this is to put the static variable in a static function and call that instead. Local static variables are initialized when execution reaches their declaration the first time, so it is always properly ordered.
template<typename T>
class A
{
public:
static auto& l() {
static std::list<A<T>*> instance;
return instance;
}
A( T t ) : val( t ) { l().push_back( this ); }
~A() { l().remove( this ); }
T val;
void print() { std::cout << val; }
};
Non-const global variables should however be avoided as much as possible in the first place. They usually make reasoning about the code more complex and have problems such as initialization order here.
I don't know what the purpose of the instance list here is, but it has similar issues and should probably be avoided if possible. Additionally it will have quite bad performance, especially if you have many instances of A<T> around, because l.remove( this ); will take linear time in the number of elements in the list. Consider using std::set or std::unordered_set instead of std::list.
Additional notes:
The return type of main must be int in C++. void as return type is a non-standard extension of some compilers.
Your class is violating the rule of 0/3/5. You need to define copy (and move) constructor and assignment operator with correct semantics, otherwise your instance list will not contain all instances when your class is copied.
You also might want to save const A<T>* instead of A<T>* in the list. The latter is dangerous. If you ever declare a variable of type const A<T>, then the pointer you save in the list will still be non-const. If you then use the pointer from the list to modify the object, you will not be warned that you are trying to modify a const object (which causes undefined behavior).
Using a block scoped static variable (local static variable in a function / static function) is very good approach because initialization of class template static data members and other static/thread-local variables are indeterminately sequenced with respect to each other and this causing problem of accessing a variable which is not yet initialized. read more about it, at Static non-local initialization
But this approach will not allow to use A<T>::l, because then, std::list<A<T>*> l variable is not static member of class A<T>, It means if static member of a class can't be avoided due to some requirements then this unordered initialization problem has to be resolved.
Now unordered initialization can be converted into ordered initialization by using explicit template initialization, as follows,
template class A<int>; //explicit template initialization
A<int> temp(1);
It will make sure that std::list<A<T>*> l get initialized before temp object initialization. This explicit template initialization has to be done in each translation unit where you want to create non-local variable of A<T>. Let's look at the code,
Header file is similar (no change),
Source file
#include "Header.h"
template class A<int>; //explicit template initialization
A<int> temp(0);
int main(int , char *[]){
std::cout<< "temp.val = ";
temp.print();
std::cout<< '\n';
}

Making an unknown class instance

This sounds simple, but right now I am utterly confused. How can I prevent an instance of a class to go out of scope without including the class definition in my header file? Can I use some kind of forward reference. I use C++ VS2017. I hope that the following pseudo-code makes my intention clear.
// MyHeader.h
class X
{
class ThirdPartyClass &tpc; // This must require a forward definition
// and many other things
}
// My program
#include "MyHeader.h"
int main ()
{
X x;
foo(x);
}
// A separately compiled module
#include "MyHeader.h"
#include "ThirdPartyClass.hpp" // (Very large)
void foo (class X &x)
{
ThirdPartyClass localtpc;
x.tpc = &localtpc;
}
I know it won't win a trophy for best code. What I want to do is keeping the instance of localtpc in memory after foo() exits. ThirdPartyClass.hpp is enormous and I don't want to include ThirdPartyClass.hpp in my MyHeader.h. Using a void * to hold a reference does not work, the instance of localtpc gets destructed. ThirdPartyClass maintains a reference count, but it cannot be explicitly manipulated.
Any insight would be greatly appreciated.
HJB
The first thing to note here is that since you've defined tpc as a reference, it must be initialized (not just assigned to), so something even on the general order of x.tpc = &localtpc; just won't work.
As to what will work, I can see (at least) two obvious possibilities. One creates a single instance of ThirdPartyClass, and then initializes all the X objects to contain pointers to that single instance:
// X.h
class X {
ThirdPartyClass &x;
public:
X();
};
// X.cpp
#include "ThirdPartyClass.hpp"
X::X()
: x(holder())
{}
ThirdPartyClass &holder() {
static ThirdPartyClass foo;
return foo;
}
The other obvious possibility would be to use new to create an instance, and initialize your reference from there:
// X.h
class X {
ThirdPartyClass &x;
public:
X();
};
// X.cpp
#include "ThirdPartyClass.hpp"
X::X()
: x(* new ThirdPartyClass)
{}
As to which is preferred: it really depends on how you're using things. If you expect all instances of x to share a single instance of ThirdPartyClass, so (for example) a modification via one should be reflected in all the others, then you almost certainly want something at least vaguely similar to the former.
On the other hand, if each instance of x is expected to have a unique instance of ThirdPartyClass, then you almost certainly want something more like the latter.

How should I access a function of a container class in a contained class object

I have the following class structure
class containingClass
{
int func1(int a);
containedClass containedClassObject;
}
I want to access func1 in containedClass objects. What will be the best way to achieve that?
A naive solution that comes to mind is to pass a function pointer to the containedClass's constructor, but then I get into a circular definition, as I need to pass a pointer to an object of the containingClass as well.
Any suggestions?
The containedClass required a contract/API/function to be fulfilled by the int func1(int) member of the containingClass. Unless the containedClass explicitly requires access to an instance of the containingClass for other purposes, the access can be provided via lambda (or std::bind) and the containedClass can have a std::function with the correct signature member that holds the lambda.
The only "trick" here would be to ensure that the lifetime of the objects are managed appropriately, i.e. the lifetime of the containingClass instance is at least as long as required for use in the containedClassObject object.
A sample;
#include <functional>
class containedClass {
std::function<int(int)> functor_;
public:
void setter(std::function<int(int)> functor) { functor_ = functor; }
};
class containingClass
{
int func1(int a);
containedClass containedClassObject;
public:
containingClass()
{
containedClassObject.setter([this](int a) -> int { return this->func1(a); });
}
};
Even if this already over a year old, I would like to help other seraching people.
Here is another example using a reference to the containing class. Tested with mingw32-g++ 4.9.2 and -std=c++98. Means it should work also with c++0x and c++11
#include <string>
#include <iostream>
using namespace std;
class clsDog;
class clsEar{
public:
clsDog& myDog;
clsEar(clsDog &dog);
};
class clsDog{
public:
clsEar ear;
void pain(string fromPart){
cout << "dog has pain in his " << fromPart << endl;
}
clsDog():ear(*this){};
};
clsEar::clsEar(clsDog &dog): myDog(dog){
myDog.pain("ear");
}
int main(){
clsDog dog;
}
First class clsDog makes it available for reference and pointers. NOT for actual values like non reference member variables.
In class clsEar a reference to clsDog is created using clsDog& myDog. The constructor can set the reference pointer in the initializer list. It is important that the containing class clsDog is passed by reference otherwise the compiler tell you that the class incomplete.
Because clsEar is now fully defined a normal member variable of clsEar can be defined in clsDog. Because clsEar's constructor needs a reference to clsDog it must be passed to it's constructor. This is done in the initialisier list of clsDog's constructor by passing *this.
Last but not least the implementation of clsEar::clsEar must be done. It is necessary to do this after the complete definition of clsDog to call the member functions or access member varibales of clsDog in clsEar. Otherwise the compiler will tell you again, that the class clsDog is of incomplete type.

Using C++ non-static member functions as callbacks and class scope issue

My code contains the following:
1) A.h (cannot be changed by me as it's defined by somebody else)
typedef void (*fnctPtr)(int input);
class A
{
A(fnctPtr func); //Constructor for A
//... Other details omitted
};
2) B.h (my code)
#include "A.h"
class B
{
public:
B() : m_a(m_private_method){}; //Ptr to non static method.
void m_private_method(int input);
A m_a; //Member variable
};
3) A simple main.cpp declaring and instance of B
#include <iostream>
#include "B.h"
int main()
{
B b;
return 0;
}
It does not compile, as m_a requires initialization with a fnct pointer of type void (*)(int input), not void (B::*)(int input).
Any advice on how to achieve what I want?
Thanks
If you're really stuck with typedef void (*fnctPtr)(int input);, then you have to provide a pointer to a function that takes a int as parameter and returns nothing.
When you' providing a pointer-to-member function of class B taking an int and returning nothng, you really provide either something that can be seen as:
either function taking two arguments, the instance of the classB and an int.
or a virtual function that need to lookup in B instance to know what function taking two arguments (B and int) to call.
There is no way to make any of those fit into the first definition.
You may find a hack (keeping an instance globally and using it inside an helper function would be one), but this is highly dependent of the full problem.

How to ensure in run-time that a member function in an inherited class is private? (C++, gcc)

A is a base class, B is an inherited class. A takes member function pointers from B bound with boost::bind+boost::function to store and execute from other base class functions later. The A and B classes are in separate include files. I would like to restrict the developer who implements inherited classes from A that the bound member function pointers in the inherited classes are private functions. The environment is C++, gcc 4.x and Linux.
Sample:
------ INCLUDE FILE -----
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct A
{
protected:
void Register(const char* name, boost::function<void()> FuncPtr)
{
// (I am not intended to pass the name argument, but probably somebody
// knows something gcc magic which would use it to solve the problem.)
// I want to ensure that FuncPtr points to a private member
// function. What can be known: "B::CalledFunction" string and FuncPtr.
// If it is not a private member function then drop an error message
// during run-time or during compilation (???).
}
};
------ OTHER INCLUDE FILE -----
...
struct B : public A
{
B() : A()
{
Register("B::CalledFunction", boost::bind(&B::CalledFunction, this));
}
private:
void CalledFunction()
{
}
};
Any kind of macro magic or similar stuff can also be appreciated before/instead of a simple direct call to A::Register().
Rather than expand the comments, I will propose an alternative based on really using inheritance
#include <iostream>
#include <memory>
class A
{
public:
void call_a() { some_func_a(); }
private:
virtual void some_func_a() = 0; // pure virtual
};
class B : public A
{
private:
void some_func_a() { std::cout << "B::some_func_a" << std::endl; }
};
int main(void)
{
std::auto_ptr<A> a(new B);
// a->some_func_a(); // causes compiler error
a->call_a();
}
If you leave out the definition of some_func_a in B, you'll get a compiler error when you try to instantiate B.
Unfortunately, the restriction you ask for is not possible. Access restrictions are only present at compile time, not runtime; the only thing they do is control (based on lexical scope) what identifiers can be referenced.
Since the calling context producing these bound member functions obviously has access to all its member functions, you cannot distinguish between private and public member functions locally - this rules out any macro hacks. Further, member function pointers do not retain access control information (this is why you can call a pointer to a private member function from another class). As such, checking elsewhere is also not possible.
You may be able to implement this as a compiler pass in something like clang, as the information is available there at compile time; however this is not possible with a normal C++ compiler. However, this may be prone to false positives and false negatives, as the situation in which this is an issue is somewhat ill-defined (what if some derived class B really wants a bound public member function, that it'll use elsewhere?)