how can I call a method from another class? - c++

I have 3 files pos.h pos.cpp and main.cpp .... I am trying to call a function from pos.cpp in the main class for instance :
pos.h file
class pos {
public:
pos(); //defualut constructor
int open_port();
}
pos.cpp
#include "pos.h"
int Open_port() {
//do stuff here
return 0;
}
class main.cpp
#include "pos.h"
int main(int argc , char** argv) {
pos pos1;
pos1::Open_port();
}
Problem is I always get that pos1 is not a class or namespace I am compining as follows
g++ mainpos.cpp pos.cpp pos.h -o position -lpthread
Any thoughts ?

You seems to have several issues in the code:
int open_port();
is a member function of pos. However, when you define it, you are not using :: operator and the function name is changed.
Try:
int pos::open_port()
{ ///^^pay attention to typos
//do stuff here
return 0;
}
Then inside main. you can do:
pos pos1;
pos1.open_port();
If you really mean Open_port(), which is not a member of the class, then you need to add function declaration into the proper header files and use it properly, but that's a separate issue.

You've several problems, most of them related to fundamental syntax:
Case matters. open_port and Open_port are two completely different things
You're not actually defining the method of the class pos, you're making a new function
int Open_port() {
needs to be
int pos::open_port() {
You're trying to invoke a non-static method statically. You need to create an instance of pos, (which you've done, pos1) and invoke open_port on it via pos1.open_port(). You cannot call pos::open_port directly, unless you declare the method static.
A final problem would be that you've declared but not defined the default constructor for your class. You need to provide a method body for pos::pos().

Well, you have two problems with your code. In the cpp file you need to use the scope for that function, so you need to have:
int pos::Open_port()
Also, you need to ensure that open_port and Open_port are spelled and capitalized the same.
Last thing, if you want to call open_port like that, you'll need to decare the function as static in the class def'n.

Related

Functions out of scope error C++

My code has a class compROS. I have created 2 functions requestStart and requestNotStart which are trying to call is_started_ and sec_ from class compROS. Now whenever I run the code, I get the following errors:
functions requestStart and requestNotStart and is_started_ and sec_ were not declared in this scope.
My assumption is that the private functions are not accessible from the outside of the class. Should I add requestStart and requestNotStart as friend functions??
What is the most efficient way of tackling these errors?
Following is my code -
(Updated my code based on the comments from #Snps and #Philip Brack)
using namespace std;
namespace Lib
{
class compROS
{
public:
compROS(string error_text, int sec):
error_text_(error_text),
is_started_(false),
sec_(sec)
{
}
private:
string error_text_;
bool is_started_;
int sec_;
};
}
int requestStart(Lib::compROS& c)
{
if(!c.is_started_)
sec_ = 2;
// Start timer
// Timer expired
c.is_started_ = true;
return 0;
}
int requestNotStart(Lib::compROS& c)
{
// <Code to be inserted>
return 0;
}
int main (int argc, char **argv)
{
Lib::compROS c("error", 2);
requestStart(c);
requestNotStart(c);
return 0;
}
int compROS::requestStarted() { } after the class definition will scope the member function to your object. Your issue is that you are declaring a function but not binding it to compROS class so you cannot access the instance members.
When you create a class in c++, what is usually included are the functions that this class will use(or may use), as well as the variables it needs in order to runs those functions. In your case, your requestStart() and requestNotStart() functions are not included in your compROS class as you don't have the actual function calls in your class. This is why when you try to run your program, your functions requestStart() and requestNotStart() are trying to find the variables is_started_ and sec_ but does not find it since those variables only exist INSIDE the class whereas your functions are OUTSIDE of your class. My suggestion is to put the function signature for both the requestStart() and requestNotStart() method in public: and simplify your compPOS method by only using the function signature and actually implement the method outside of the class.
In object-oriented programming, a class definition is like a blueprint of a house. You can not use the kitchen, nor the bathroom, of the blueprint, the only thing you can do is to use it to build a house.
In the same way, you can not call any methods of your class until you have built an instance of that class.
Lib::compROS c("my error", 2);
Any function that wants to call any of your class' methods needs to know on what instance to make the call. You need to somehow pass a reference to an instance of your function.
int requestStart(Lib::compROS& c) {
if(!c.is_started_)
sec_ = 2;
// Start timer
// Timer expired
c.is_started_ = true; // This member needs to be public for external access.
return 0;
}
int main() {
Lib::compROS c("my error", 2); // Create instance.
requestStart(c); // Pass instance to function.
}

Using a function name that is already taken

Let's assume some third-party developer writes a function
int GetErrorCode(const object * p);
This function returns only certain int values, thus I am tempted to write my own ErrorCode enum class, that contains all the possible return values. Then write a bit updated function:
enum class ErrorCode : int {};
ErrorCode GetErrorCode2(const object * p){
return (ErrorCode)GetErrorCode(p);
}
The problem is I want my function to be named GetErrorCode and not that less-intuitive GetErrorCode2.
How can I possibly achieve that? Maybe there is a way to swap function names or something?
Use namespaces:
namespace MyLibrary {
ErrorCode GetErrorCode(const object *p) {
int origResult = ::ErrorCode(p);
// use :: to explicitly call outer function to avoid recursion
...
}
}
Then you can call the function as:
MyLibrary::GetErrorCode(obj);
Put your function in a namespace that you normally use. You might have a using namespace foo; - er better yet, using foo::GetErrorCode; - for it where you use it, preferably in a function's body.

c++ Error when Testing library

I am creating an Arduino library which takes two constructors for a personal project of mine, but for some reason I keep getting an error which is specific to types, first let me show you how the structure goes. so here is my files:
this is the header file:
#ifndef iGA_H
#define iGA_H
class iGA {
public:
getParameters(int soundA[], int soundB[], int parentId[]);
private:
int _soundA[];
int _soundB[];
int _parentId[];
}
the cpp file:
#include <iGA.h>
iGA::getParameters(int soundA[], int soundB[], int parentId[])
{
_soundA = soundA;
_soundB = soundB;
_parentId = parentId;
}
And this is how im pretty much calling the constructor in the sketch, within the setup() function:
#include <iGA>
iGA iga;
void setup() {
iga.getParameters(r, r1 , r2);
}
and here is the error:
In file included from /home/bargros/Dropbox/iGA__NewBild/iGA__NewBild.ino:34:0:/home/bargros/Arduino/libraries/iGA/iGA.h:10:58: error: ISO C++ forbids declaration of 'getParameters' with no type [-fpermissive]getParameters(int soundA[], int soundB[], int parentId[]);
I know the error has something to do with argument types or maybe im calling the constructor wrongly but I also tried calling it like this:
iGA iga = getParameters(etc,etc,etc);
im relatively new to c++ and im a little clueless as to what this error is telling me. Does anyone have any sort of idea of why this happens?
I believe two issues:
Issue 1: Your function should return something right? you may want to set it as void if it just meant to assign the parameters to the private members (it is a setter and not a get in your case). Add void in the proper locations both inside the class and when you write its definition.
Issue 2: I think that you can't send an array[] as a parameter. And I assume that you already know the size. You need, instead, to send a pointer that points to the first element of the array along with the size of the whole array. Then, once you receive the parameters, for every private member, you create a new array with the size received (or just fill the private member directly) and fill the values by iterating the received array using the pointer received.
Edit: I just checked and passing int array[] should be fine. So fixing issue one will fix your problem. See here for further documentation.
In C++ you have to be explicit that a function doesn't return anything, which you do by saying it returns void:
getParameters(int soundA[], int soundB[], int parentId[]);
needs to be
void getParameters(int soundA[], int soundB[], int parentId[]);
and
iGA::getParameters(int soundA[], int soundB[], int parentId[])
needs to be
void iGA::getParameters(int soundA[], int soundB[], int parentId[])

Vector Public in Class - Can't Use in Implementation?

Here's my situation. I have a class in which I have defined a vector publicly, as below:
class TrackObjects
{
public:
vector<MovingObj> movingObjects;
...
etc.
It has a constructor and everything. I have a separate .cpp file with some implementations where I'm trying to use that vector and methods on that vector. As one example, it's part of a condition in a function like so:
if (movingObjects.locX >= x1)
...
etc.
It tells me movingObjects is undeclared, and to first use this function. It's not a function, and to my knowledge, I haven't called it like one/tried to use it like one.
Can anyone suggest why I might be getting this error?
EDIT: locX is a public variable in the another class MovingObj. TrackObj is the class that creates the vector for objects MovingObj creates. Sorry, I really should've specified that. Like so:
class MovingObj {
public:
MovingObj(int inId, int inLocX, int inLocY, int inWidth, int inHeight);
int id, locX, locY,width,height;
Based on what you are telling us, the proper way to access locX would be something along the lines of:
TrackObjects objs;
objs.movingObjects[15].locX = 123.45;
Or, maybe:
if(objs.movingObjects[15].locX >= 15)
{
//do something
}
You can also encapsulate your access method in TrackObjects (put this in your TrackObjects.cpp implementation):
bool TrackObjects::testLocX(int pos)
{
if(movingObjects[pos].locX>=15)
return true;
return false;
};
This is an elementary C++ issue. movingObjects is part of an object. Code that is not part of the TrackObjects class can only access movingObjects by specifying which object's movingObjects you wish to access.
if (someobject.movingObjects.size() > 0)
...
Another issue is that to access such an object from another cpp file you will first have to #include the file that contains the class definition.

Accessing private fields and function from main

I've programmed only in Java in my career and started using C++ since 10 days, so this question may seem strange to many of you.
I have defined the structure of a class in a header file:
#include "ros/ros.h"
#include "nav_msgs/Odometry.h"
#include "geometry_msgs/Pose.h"
#include "geometry_msgs/Point.h"
#include "stdio.h"
#include "sensor_msgs/LaserScan.h"
#include "list"
#include "vector"
#include "scan_node.h"
#include "odom_node.h"
#include "coord.h"
class stage_listener{
public:
stage_listener();
private:
std::list<odom_node> odom_list;
std::list<scan_node> scan_list;
std::list<coord> corners_list;
std::list<coord> polar2cart(std::vector<float>, float, float, float, float);
void addOdomNode (const nav_msgs::Odometry);
void addScanNode (const sensor_msgs::LaserScan);
void extractCorners(std::vector<float>, float, float, float, float);
int distance (float, float, float, float, float);
void nodes2text(std::vector<odom_node>, std::vector<scan_node>);
int numOdom();
int numScan();
};
In the associated .cpp file, I wrote a main:
int main(int argc, char **argv){
char buffer [1024];
while(1){
int i = fscanf(stdin,"%s",buffer);
if(strcmp("exit",buffer) == 0)
exit(0);
else if(strcmp("num_nodes",buffer) == 0){
ROS_INFO("Odometry nodes: %i\nScan nodes: %i",numOdom(),numScan());
}
else{}
}
}
The ROS_INFO function is part of Willow Garage's ROS and you can intend it like a normal printf, taking exactly arguments in the same form.
On compiling code, I get the following:
/home/ubisum/fuerte_workspace/beginner/src/stage_listener.cpp: In function ‘int main(int, char**)’:
/home/ubisum/fuerte_workspace/beginner/src/stage_listener.cpp:223:5: error: ‘numOdom’ was not declared in this scope
/home/ubisum/fuerte_workspace/beginner/src/stage_listener.cpp:223:5: error: ‘numScan’ was not declared in this scope
Do you know the cause of the errors? In Java, you can access private fields/functions, so I can't understand the reason why in C++ it's not possible.
In Java, you can access private fields/functions
No you can't, unless you're using reflection. That's the entire point of making something private. I think you're mixing up public and private here. (You can access private static fields and methods in java from the classes own main method though). The main function in C++ is not associated with a class (and even if it were, your code still wouldn't work because you're attempting to access instance members statically).
There are a few things here.
Firstly, you need to make stage_listener object to call its methods or make methods static then use scope resolution operator to call the functions if you want objects to share same method.
Secondly, you cannot access private variables( that is the point of data hiding in OO languages.)
So, you need to make functions public in the class and either create object of the class or make functions static and call them using scope resolution operator. Depends totally on what are you trying to accomplish. I hope this helps.
Usually, in C++, we use the functions as a public.
You did it as private, so just in the scope of own class you'll can access them. So, if yoy're trying to use them in the main, we can think that these functions should be public.
And you need to declare an object of the class. So you'll can access the function using object.function(); command.
1) You can't call methods without instantiating the class, or simply put you have to create object first.
2) Even if you create an object of your class your object can't call private methods. So make numOdom and numScan public methods.
You can't access any private method outside of on of this class's method (even in Java).
Set the methods you want to use outside as public
In C++, the main function is not part of the class you defined (even though it's "in the associated .cpp file"), so it can't access private fields. In C++ as in Java, only functions that are declared in the class are part of the class, and so can access private fields.
1) Public methods in the public section
2) To call the non-static public methods of the class, first create an instance of the class
class stage_listener{
public:
stage_listener()
{
}
//all methods are not implemented
void addOdomNode (const nav_msgs::Odometry) {}
void addScanNode (const sensor_msgs::LaserScan) {}
int numOdom() { return 0; }
int numScan() { return 0; }
private:
std::list<float> odom_list;
........
std::list<float> polar2cart(std::vector<float>, float, float, float, float)
{
//empty list
return std::list<float>();
}
........
};
int main(int argc, char **argv){
char buffer [1024];
while(1){
int i = fscanf(stdin,"%s",buffer);
if(strcmp("exit",buffer) == 0)
exit(0);
else if(strcmp("num_nodes",buffer) == 0){
//create object on the stack
stage_listener sl;
ROS_INFO("Odometry nodes: %i\n
Scan nodes: %i\n",
sl.numOdom(),
sl.numScan());
}
else{
return 1;
}
}
return 0;
}