Arduino C++ classes needing each other - class

Here an example relating to my problem:
class classA
{
private:
int Value = 100;
public:
int get_Value()
{
return Value;
}
void set_Value(int p)
{
if (p == 0) Value = B.get_Value();
else Value = 5;
}
};
classA A = classA();
class classB
{
private:
int Value = 200;
public:
int get_Value()
{
return Value;
}
void set_Value(int p)
{
if (p == 0) Value = A.get_Value();
else Value = 5;
}
};
classB B = classB();
The problem is that class A can't access class B because it's definition is below it's own. My question is how can I define it so that class A has access to class B.
I tried to something like class classB; or class classB; classB B = classB; before classA begins.
Because I'm relatively new to programming I don't know how to solve such (probably easy) problems. Hope for some help!

This is a problem with circular dependencies. Luckily this one is pretty easy to fix: Just put the declaration and definition into separate files.
ClassA.h:
// Include guards to prevent double includes
#ifndef CLASS_A_H
#define CLASS_A_H
class classA
{
private:
int Value = 100;
public:
// Here we only declare, but not define the functions
int get_Value();
void set_Value(int p);
};
#endif // CLASS_A_H
ClassB.h:
// Include guards to prevent double includes
#ifndef CLASS_B_H
#define CLASS_B_H
class classB
{
private:
int Value = 200;
public:
// Here we only declare, but not define the functions
int get_Value();
void set_Value(int p);
};
#endif // CLASS_B_H
And now we need to actually define the functions, but in different files
ClassA.cpp:
#include "A.h"
#include "B.h"
// Use extern to tell the compiler that this declaration can be
// found in any of the other files and it will not complain as
// long as it is found somewhere
extern classB B;
int classA::get_Value()
{
return Value;
}
void classA::set_Value(int p)
{
if (p == 0) Value = B.get_Value();
else Value = 5;
}
ClassB.cpp:
#include "A.h"
#include "B.h"
// Use extern to tell the compiler that this declaration can be
// found in any of the other files and it will not complain as
// long as it is found somewhere
extern classA A;
int classB::get_Value()
{
return Value;
}
void classB::set_Value(int p)
{
if (p == 0) Value = A.get_Value();
else Value = 5;
}
Then, in your main file just include the two headers and you're good to go:
#include "A.h"
#include "B.h"
classB B = classB();
classA A = classA();
By the way, when you're on Arduino you can just create new .h and .cpp files and put them next to the .ino file and it should be found. You can even put them in folders, but then the include paths must be relative to each files, for example: #include "../include/file.h"

Related

Binary Operator overloading for a member enum class (with non static members)

The following code doesn't compile.
error: invalid use of non-static data member 'data'
#include <iostream>
#include <unordered_map>
#include <vector>
class Domain {
public:
enum class fieldname { x_, y_ };
std::unordered_map<fieldname, std::vector<double>> data;
// default constructor. Hard coding is only for this test!
Domain() {
data[Domain::fieldname::x_] = std::vector<double>{1, 23, 4};
data[Domain::fieldname::y_] = std::vector<double>{1, 23, 4};
}
// operator overloading
friend std::vector<double> operator+(fieldname one, fieldname two) {
std::vector<double> result = data[one]; // so we get the right size
for (int i = 0; i < result.size(); ++i) {
result[i] = data[one][i] + data[two][i];
}
return result;
}
};
int main() {
Domain d;
std::vector<double> temp = Domain::fieldname::x_ + Domain::fieldname::y_;
for (auto item : temp) std::cout << item << std::endl;
return 0;
}
I think it is evident from the code what I am trying to accomplish. Could someone suggest how the operator + can be overloaded so that the enum classes can be used as a proxy for vectors which are members of a class?

Creating class object c++ in if-statement

I actually have a small question. I want to create an attribute "function" which should be from the class function1, function2 or function3. Is there a way I can do that?
Here is the code:
double Uppersum::evalIntegral(double p_) {
if (functiontype == FUNKTION1){
Function1 function;
}
else if (functiontype == FUNKTION2) {
Function2 function;
}
else if (functiontype == FUNKTION3){
Function3 function;
}
function.setParameterP(p_);
double increment_h = (boundary_b - boundary_a)/num_subintervalls_m;
double sum = 0;
for (int index_i = 0; index_i < num_subintervalls_m -1; index_i++){
double x_1 = index_i * increment_h;
double x_2 = (index_i+1) * increment_h;
double y_1, y_2;
y_1 = function.evalFunctionValue(x_1);
y_2 = function.evalFunctionValue(x_2);
sum += increment_h * std::max(y_1, y_2);
}
}
class Function {
protected:
double parameter_p;
public:
void setParameterP(double p_);
virtual double evalFunctionValue(double x_)=0;
};
class Function1 : public Function {
public:
double evalFunctionValue(double x_);
};
Why not use inheritance, superclass has the virtual functions setParameterP and evalFunctionValue. and in subclasses, override those virtual functions.
here is the test codeļ¼š
test.cpp
#include <iostream>
typedef enum{
FUNCTION1,
FUNCTION2,
FUNCTION3
}FunctionType;
using namespace std;
class super
{
public:
super(){}
~super(){}
virtual void setParameterP() = 0;
virtual void evalFunctionValue() = 0;
};
class func1:public super
{
public:
func1(){}
virtual void setParameterP(){cout<<"call setParameterP In func1"<<endl;}
virtual void evalFunctionValue(){cout<<"call evalFunctionValue In func1"<<endl;}
};
class func2:public super
{
public:
func2(){}
virtual void setParameterP(){cout<<"call setParameterP In func2"<<endl;}
virtual void evalFunctionValue(){cout<<"call evalFunctionValue In func2"<<endl;}
};
class func3:public super
{
public:
func3(){}
virtual void setParameterP(){cout<<"call setParameterP In func3"<<endl;}
virtual void evalFunctionValue(){cout<<"call evalFunctionValue In func3"<<endl;}
};
class FuncFactory
{
public:
static super* create(FunctionType var)
{
super* ret = nullptr;
switch (var)
{
case FUNCTION1:
ret = new func1();
break;
case FUNCTION2:
ret = new func2();
break;
case FUNCTION3:
ret = new func3();
break;
default:
cout <<"invalid FunctionType" << endl;
}
return ret;
}
};
int main(int argc, char** argv)
{
super* pFunc = FuncFactory::create(FUNCTION1);
pFunc->setParameterP();
pFunc->evalFunctionValue();
delete pFunc;
pFunc = FuncFactory::create(FUNCTION2);
pFunc->setParameterP();
pFunc->evalFunctionValue();
delete pFunc;
pFunc = FuncFactory::create(FUNCTION3);
pFunc->setParameterP();
pFunc->evalFunctionValue();
delete pFunc;
return 0;
}
here is the process result:
result

How to define the operator= in a class to make a variable in it to be assigned to an outside variable

I have example code and classs:
class a{
int x;
a(){
this->x = 335; /* example number*/
}
public:
void operator=(int);
};
void a::operator=(int source){
this->x = source;
}
main(){
int i = 100;
a example_class;
example_class = i; //works fine!
i = example_class; /*this is what I want to do.*/
}
the problem with this hole thing is that I can't
make the operator= be a friend function
therefore the command: "i = example_class"
can't be done because I can't create a function in //the the int class like I normally would with my own classes.
Finally:
How can I complete the command:
"i = example_class" when the
operator= can't have more than 1
parameter?
notes:
I know the code doesn't do anything.
And is only an example. The point
Is what actually matters.
Also, I need to make it clear that I
cannot create any functions in the
Target class(in this case int). Only in
the source class(in this case a).
I also want to make clear that I know
that it's impossible to declare the
operator= as a friend function.
I know that I could just create a function
to get a reference to int x or make
int x public but I didn't want to do that
because the real code involves complex
functions for converting between types
so it's vary important to me to be able
to write: "i = example_class;".
Thanks,
Ronen.
Working example.
#include <iostream>
class a {
int x = 355;
public:
void operator=(int);
operator int();
};
void a::operator=(int source){
x = source;
}
a::operator int() {
return x;
}
int main(int, char**) {
int i = 100;
a example_class;
example_class = i;
int j = example_class;
std::cout << j << std::endl;
}

smart pointer to manage socket file descriptor

A smart pointer clears the memory if the pointer gets out of scope. I wanted to adapt this to a file descriptor, like a socket. There you need a user defined deleter, because close() is the function to free the file descriptor (fd) resources.
I found this useful page, unfortunately, most approaches did not work for me. Below is a working solution I found up to now, which is a little nasty. Because uniqu_ptr expects a pointer I created int *fd to store the fd value, therefore, I had to close(*fd) and delete fd in my custom deleter.
(1) Is there a better way?
Options A and B, which are based on the hints provided by the mentioned web page, are much nicer but causing odd compiler errors.
(2) Does anyone know how to correctly use these alternatives?
I'm using Qt Creator 3.0.1 with CONFIG += c++11 option and gcc version 4.8.2
#include "ccommhandler.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <memory>
#include <qdebug.h>
//for Option A and B
struct CloseHandleDeleter {
typedef int pointer;
void operator()(int handle) const
{
}
};
//custom deleter, working
class MyComplexDeleter
{
public:
MyComplexDeleter() {}
void operator()(int* ptr) const
{
qDebug() << "Deleting ";
close(*ptr);
delete ptr;
}
};
CCommHandler::CCommHandler()
{
//Option A doesn't work
//std::unique_ptr<int, CloseHandleDeleter> file( socket(AF_INET, SOCK_STREAM, 0) );
//Option B doesn't work
//std::unique_ptr<int, int()(int)> filePtr( socket(AF_INET, SOCK_STREAM, 0) , close);
MyComplexDeleter deleter;
int *fd = new int;
*fd = socket(AF_INET, SOCK_STREAM, 0);
std::unique_ptr<int, MyComplexDeleter> p( fd , deleter);
}
Edit:
The posted answer by Nevin is right, it solves my initial problem.
The comment of learnvst caused to rethink my problem, and I have to say I may made it much more complex than needed, because the following simple class should also solve my problem of auto-free the memory of a resource or as in my case, to close the file descriptor:
class SocketHandler
{
int _fd;
public:
SocketHandler(int FD):_fd(FD){}
~SocketHandler() { if(_fd!=-1) close(_fd); }
operator int() const { return _fd; }
};
Because fd isn't a pointer, I wouldn't try to pigeonhole it into unique_ptr. Instead, create a custom class whose interface is based on unique_ptr, as in (caution: totally untested):
class unique_fd
{
public:
constexpr unique_fd() noexcept = default;
explicit unique_fd(int fd) noexcept : fd_(fd) {}
unique_fd(unique_fd&& u) noexcept : fd_(u.fd_) { u.fd_ = -1; }
~unique_fd() { if (-1 != fd_) ::close(fd_); }
unique_fd& operator=(unique_fd&& u) noexcept { reset(u.release()); return *this; }
int get() const noexcept { return fd_; }
operator int() const noexcept { return fd_; }
int release() noexcept { int fd = fd_; fd_ = -1; return fd; }
void reset(int fd = -1) noexcept { unique_fd(fd).swap(*this); }
void swap(unique_fd& u) noexcept { std::swap(fd_, u.fd_); }
unique_fd(const unique_fd&) = delete;
unique_fd& operator=(const unique_fd&) = delete;
// in the global namespace to override ::close(int)
friend int close(unique_fd& u) noexcept { int closed = ::close(u.fd_); u.fd_ = -1; return closed; }
private:
int fd_ = -1;
};

member function as callback

I would like to pass a member function of an instantiated object to another function. Example code is below. I am open for any strategy that works, including calling functional() from another function inside memberfuncpointertestclass using something like lambda or std::bind. Please note that I did not understand most of the threads I found with google about lambda or std::bind, so please, if possible, keep it simple. Also note that my cluster does not have C++ 11 and I would like to keep functional() as simple as it is. Thank you!
int functional( int (*testmem)(int arg) )
{
int a = 4;
int b = testmem(a);
return b;
}
class memberfuncpointertestclass
{
public:
int parm;
int member( int arg )
{
return(arg + parm);
}
};
void funcpointertest()
{
memberfuncpointertestclass a;
a.parm = 3;
int (*testf)(int) = &a.member;
std::cout << functional(testf);
}
int main()
{
funcpointertest();
return 0;
}
You cannot invoke a method on an object without an instance to refer to. So, you need to pass in both the instance as well as the method you want to invoke.
Try changing functional to:
template <typename T, typename M>
int functional(T *obj, M method)
{
int a = 4;
int b = (obj->*(method))(a);
return b;
}
And your funcpointertest to:
void funcpointertest()
{
memberfuncpointertestclass a;
a.parm = 3;
std::cout << functional(&a, &memberfuncpointertestclass::member);
}
This is a job for std::function, a polymorphic function wrapper. Pass to functional(...) such a function object:
#include <functional>
typedef std::tr1::function<int(int)> CallbackFunction;
int functional(CallbackFunction testmem)
{
int a = 4;
int b = testmem(a);
return b;
}
then use std::bind to create a function object of the same type that wraps memberfuncpointertestclass::method() of instance a:
void funcpointertest()
{
memberfuncpointertestclass a;
a.parm = 3;
CallbackFunction testf = std::bind(&memberfuncpointertestclass::member, &a, std::placeholders::_1);
std::cout << functional(testf);
}
Check this item for more details.