Functions out of scope error C++ - 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.
}

Related

How to modify the same variable in different classes and modify it?

I have many function definitions which I have placed in different cpp files with function declarations in their respective .h files.
I have a set of a variables which I have placed in a .h file. These variables need to modified by different functions. I am using static to keep the changes from each function, but I heard it is a bad coding practice. How else to do it ? For eg -
variables.h
class variable{
static int x;
static int y;
};
function1.h
class function(){
public:
void function1();
}
similar for function 2
function 1.cpp
void function1(){
// does something with x and y (used as (variable::x=2;variable::y=3)
}
function2.cpp
void function2(){
// does something with x and y (used as variable::x+=2;variable::y+=2)
}
main.cpp
int variable::x;
int variable::y;
int main(){
obj.function1(); (obj is object of function1 class)
obj2.function2(); (obj2 is object of function2 class)
cout << variable::x << variable::y << endl;
}
I was was using different objects in different cpp files but changes in one function were not reflecting in other. How it use it please help?
You can simply move these variables into another class:
struct Shared {
int x;
int y;
};
Now you can pass an instance to this class as parameter to your function, this is called dependency injection:
void foo(Shared& shared) {
shared.x = 4;
shared.y = 2;
}
This is better because you don't have any global state anymore. You could use the function multiple times independent from each other by referencing a different instance of the Shared class.
It is very common to take this a step further by "injecting" the instance in the constructor of that class. This is helpful if the instance of that class should always reference the same instance:
struct Foo {
Shared& m_shared;
Foo(Shared& shared)
: m_shared(shared)
{
}
void foo() {
m_shared.x = 4;
m_shared.y = 2;
}
};
Yes, as you mentioned using static variable for this purpose is kind of anti-pattern. A better pattern (without knowing the background of the application) is using a composition pattern. If your functions f1() and f2() are in classes C1 and C2, you would e. g. create an additional data object D1 (with the variables in question), and inject and object of D1 in the constructor of C1 and C2, so both classes operation on a data object. There are also other solutions to this situation, but I guess thats the most general. Google for C++ Design Pattern to find more general patterns.
You can use smart pointers for global objects
struct MyGlobal
{
std::shared_ptr<Core> core;
MyGlobal(){ core=std::make_shared<Core>(); }
void changeVariableX(int X)
{
core->X = X;
}
};
You can move, copy, do whatever you want with MyGlobal instances and they still point to same core item. Just make sure all of them are populated from same instance like this:
int main()
{
MyGlobal global;
auto something = useSomeFunctionWith(global);
auto somethingElse = useAnotherFunctionWith(global);
...
// use something and somethingElse to change X, both point to the same X
}
If functions will not be thread-safe then you should add a lock-guard into changeVariableX method.

Static Virtual Functions

Okay, so I know that static virtual functions don't exist for several reasons. I do believe, however, I have found a situation in which something mimicking them may be useful. As part of a group project for a class we must design a scripting core for a game engine. In order to keep things decoupled we want a class to be able to register its metatables (functions, members, etc) with the LuaState. Also, I could be way off here as this is my first time trying to implement anything of the sort.
So, in order to keep things generic we have an IScriptStateManager interface that contains pure virtual functions to register objects with the scripting languages global state, perform init and shutdown features, and has a couple other functions for DoFile and DoString. Then we have a LuaStateManager class that implements the functionality of this interface.
Now, in order to allow most game objects to be created in script without knowing about them ahead of time we also created an IScriptObject interface. If you want an object to be represented by the scripting system it should implement this interface. This interface includes a method that contains a method called register that derived classes can implement and will set up there metatables. So everything looks like this:
bool LuaStateManager::Register(IScriptObject* obj)
{
if (obj has not already been registered with global state)
{
obj->Register();
return true;
}
return false;
}
I'm sure you can see the problem. First and foremost we need and actual instantiation to register an object. Because of this we may be calling this function multiple times for a particular type of object, only to have it return true the first time and false every other time. While the overhead of this is minimal, it's a dead giveaway that something is wrong with the design.
So the issue arises. In this particular case we need the functionality of both a static method and a virtual method. Granted we could simply manually add static methods to each class and then call those once, but this couples objects to the scripting system. Any tips or help would be most welcome. Thanks
Provide access to the functionality of IScriptStateManager through a set of functions in an API class or a namespace.
ScriptStateManagerAPI.h:
namespace ScriptStateManagerAPI
{
// Function to register the active ScriptStateManager.
void setActiveScriptStateManager(IScriptStateManager* scriptStateManager);
// Function to register a ScriptObject.
bool registerScriptObject(IScriptObject* obj);
}
IScriptStateManager.h:
class IScriptStateManager
{
virtual bool registerScriptObject(IScriptObject* obj) = 0;
};
ScriptStateManagerAPI.cpp:
#include <IScriptStateManager.h>
namespace ScriptStateManagerAPI
{
static IScriptStateManager* activeScriptStateManager = nullptr;
void setActiveScripStatetManager(IScriptStateManager* scriptStateManager)
{
activeScriptStateManager = scriptStateManager;
}
bool registerScriptObject(IScriptObject* obj)
{
if ( activeScriptStateManager )
{
return activeScriptStateManager->registerScriptObject(obj);
}
else
{
// Deal with lack of an active IScriptStateManager.
return false;
}
}
}
LuaScriptManager.h:
#include <IScriptStateManager.h>
class LuaScriptManager : public IScriptStateManager
{
virtual bool registerScriptObject(IScriptObject* obj);
};
LuaScriptManager.cpp:
namespace
{
// Helper class in anonymous namespace to register a LuaScriptManager as
// the active IScriptStateManager at start up time.
struct Initializer
{
Initializer();
};
};
// Construct an Initializer at start up time.
static Initializer initializer;
Initializer::Initializer()
{
// Register a LuaScriptManager as the acive ScriptStateManager.
ScriptStateAPI::setActiveScriptStateManager(new LuaScriptManager());
}
bool LuaScriptManager::registerScriptObject(IScriptObject* obj)
{
if (obj has not already been registered with global state)
{
obj->Register();
return true;
}
return false;
}
You can use another ScriptStateManager in your application. Then you have to choose whether you can have only one ScriptStateManager at a time or not. If your application needs more than one ScriptStateManager at a time, you can change the static data as well as the interface in ScriptStateManagerAPI
ScriptStateManagerAPI.h:
namespace ScriptStateManagerAPI
{
// Function to register an active ScriptStateManager.
void registerActiveScriptStateManager(IScriptStateManager* scriptStateManager);
// Function to register a ScriptObject.
bool registerScriptObject(IScriptObject* obj);
}
ScriptStateManagerAPI.cpp:
#include <IScriptStateManager.h>
namespace ScriptStateManagerAPI
{
static std::set<IScriptStateManager*> activeScriptStateManagers;
void registerActiveScripStatetManager(IScriptStateManager* scriptStateManager)
{
activeScriptStateManagers.insert(scriptStateManager);
}
bool registerScriptObject(IScriptObject* obj)
{
// Figure out how to manage the return the values of each
// activeScriptManager.
for ( auto activeScriptManager, activeScriptStateManagers)
{
activeScriptManager->registerScriptObject(obj);
}
return true; //????
}
}

how can I call a method from another class?

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.

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;
}

Structure of program

I have few files:
main.cpp:
int main{
...
while(1){
...
draw();
...
}
...
return 0;
}
and draw.cpp:
I want to see objects and all manipulations here.
I cant make objects local to draw(), because draw() is inside loop,
so I will get many object constructor/destructor calls - so they are global. Also
I ve made init block to prevent unnecessary calls/assignments
draw.cpp:
Object A, B;
int initialized = 0;
void draw(){
if(!initialized){
A.initialization;
B.initialization;
initialized = 1;
}
A.move(1,1);
B.rotate(45);
}
It works, but Im looking for better way to organize my code
Added:
Thanks for answers, looks like I have to read something about pattern designs
Here's steps to make it work better:
Add a struct containing all your objects near main().
pass it to draw(MyStruct &s); via reference parameter.
you're done.
Option 1
Define a new Class called Draw and put the attributes into it. You need to modify main and draw files for this. With this you can avoid declaring anything global
Option 2
Define a class within draw.cpp called draw and add your current global variables as static member variables. Initialize and use them using static functions. With this you dont have to change main.
This design technique is called Singleton (one of the design patterns)
Example code
draw.cpp
class Draw
{
public:
object A, B;
static void init()
{
// init A
// init B
isInitialized = 1;
}
static int isInitialized;
static Object & getA()
{
if(isInitialized == 0)
{
init();
}
return A;
}
// similarly B
};