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;
}
Related
I've tried to bind free functions as class member functions, and it works (see code bellow). But I'm puzzled how it works and have some questions.
Questions:
Calling the obj_A.func_A() is the same as calling func_X() directly? Is a pointer created internally in the first approach ?
Is there an additional overhead by calling these methods via obj_A ?
Are Class_A::func_A / B really member function? It behaves like a static ones, because it hasn't access to Class_A members...
Is this a strange design pattern? Any suggestions to improve it?
#include <string>
#include <iostream>
using namespace std;
// define some (reference to) functions signatures types
using func_A_t = int (&)(const string &);
using func_B_t = double (&)(int, int);
// class that has two "methods" (func_A, func_B) whose definition come externally
class Class_A {
public:
string name;
// function members as references?
func_A_t& func_A;
func_B_t& func_B;
Class_A(string arg_name, func_A_t& arg_func_A, func_B_t& arg_func_B):
name{arg_name},
func_A{arg_func_A},
func_B{arg_func_B}
{
}
};
// external 'free' function
int func_X(const string& s) {
return s.size();
}
// external 'free' function
double func_Y(int a, int b) {
return 1.75 * a * b;
}
int main(int argc, char **argv) {
// contruct obj_A, binding the free functions (func_X, func_Y) as Class_A member functions
Class_A obj_A{"crazy test", func_X, func_Y};
int r1 = obj_A.func_A("Hello");
cout << "r1=" << r1 << "\n";
double r2 = obj_A.func_B(5, 7);
cout << "r2=" << r2 << "\n";
return 0;
}
Calling the obj_A.func_A() is the same as calling func_X() directly?
Yes
Is a pointer created internally in the first approach?
Yes (assuming you mean "in the constructor")
Is there an additional overhead by calling these methods via obj_A?
Yes. An additional level of indirection is possible, although the compiler may optimize this away depending on how you use it.
Are Class_A::func_A / B really member function?
No, they are member variables that happen to be function pointers
Is this a strange design pattern?
That is subjective, but I think not. It is used a lot in dependency injection architectures. For example, injecting details of how to obtain a handle to a database.
Any suggestions to improve it?
We'd need a pretty specific use case to provide guidance. StackOverflow may not be the best place for that discussion. For now, it's not typical to expose the injected dependency publicly. You may consider a proxy pattern where you can call-through to the function instead. This allows you more flexibility.
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.
}
I have written a library (doesn't matter what it does), which obviously has its header file. Now, I want to hide private elements of that header file, so if I provide my library to somebody, he/she should only see public members (preferably no class definition, nothing other than function definitions). One way would be creating C-style header, which will contain some kind of "init" method which will be used to create an instance of the actual class of library and the user will have to pass a pointer of that object to every function to do the job.
Is it a good practice?
Are there any other publicly accepted ways of doing something like that?
Thanks in advance.
In addition to the Factory pattern (which, in my opinion, can become unwieldy), you can also hide your private members behind a PIMPL (Pointer to IMPLementation):
// Interface.hpp
class Implementation;
class Interface {
public:
Interface() : pimpl(new Implementation()) {}
void publicMethod();
private:
std::unique_ptr<Implementation> pimpl;
};
// Interface.cpp
class Implementation {
public:
void PrivateMember();
};
void Interface::publicMethod() { pimpl->PrivateMember(); }
This has the advantage of hiding implementation, at the cost of a single pointer indirection, not much different from the typical inheritance-based Factory pattern.
This can also be ABI stable. Changes to your implementation won't affect linkage, since no changes will ever be visible to the rest of the program. This is a good pattern to use when implementing shared objects, for example.
It's also a common C++ idiom, so other C++ programmers will recognize it without question.
In the case of a class which will follow the Singleton pattern, you can avoid exposing the PIMPL at all, and simply write the entire implementation in an anonymous namespace in your .cpp file, where you can put as much state and private functions as you wish, without even hinting at it in your interface.
You can create a publicly-visible interface. Create an abstract class with the functions you want to expose, then have your implementation extend it.
For example, an interface:
class Interface {
public:
virtual void publicMethod() = 0;
...
};
And the implementation:
class Implementation : Interface {
public:
virtual void publicMethod();
private:
int hiddenMethod();
};
Then you only export the symbols for Interface. Now, in order for the user of the library to get instances of Interface which are actually Implementations, you need to provide a factory:
class Factory {
public:
//can create and return an Implementation pointer, but caller will get an Interface pointer
std::shared_ptr<Interface> getImplementationInstance();
}
Base on Eric Finn's answer, you can just declare an interface class to hold all your public methods which considered to be your API, and hide all implementations and private members/methods in implementation class which inherits interface class, here's the example:
Your header file: my_api.h
// your API in header file
// my_api.h
class interface {
public:
static interface* CreateInstance();
virtual void draw() = 0;
virtual void set(int) = 0;
};
your implementation(shared library): my_api.cpp (users won't see this when you make it a shared library)
So you can hide all your implementation and private methods/members here
#include "my_api.h"
// implementation -> in .cc file
class implementation : public interface {
int private_int_;
void ReportValue_();
public:
implementation();
void draw();
void set(int new_int);
};
implementation::implementation() {
// your actual constructor goes here
}
void implementation::draw() {
cout << "Implementation class draws something" << endl;
ReportValue_();
}
void implementation::ReportValue_() {
cout << "Private value is: " << private_int_ << endl;
}
void implementation::set(int new_int) {
private_int_ = new_int;
}
interface* interface::CreateInstance() {
return new implementation;
}
How user uses your API:
#include <iostream>
#include "my_api.h"
int main(int argc, const char * argv[])
{
using namespace std;
interface* a; interface* b;
a = interface::CreateInstance();
a->set(1);
b = interface::CreateInstance();
b->set(2);
b->draw();
a->draw();
return 0;
}
Output:
Implementation class draws
Private int is: 2
Implementation class draws
Private int is: 1
In this pattern, your api is just an abstract class which works like a factory, you can also implement the virtual method in different classes and specify which instance you would like to call.
I think you need to create Dynamic Link Library (dll).
Please take a quick look at this link:
You might want to take a look at the envelope/letter idiom, bridge design pattern, or proxy pattern. Basically, you would create an outer (public) class that would just forward your public method calls to the inner (private) class. Your InnerClass.h header only needs to be visible/known to your OuterClass.cpp and InnerClass.cpp source files.
Each of these patterns provides a mechanism of separating the implementation from the interface so that the caller is not coupled to the implementation. Sometimes this is desired to reduce compiler dependencies on large C++ projects. Another common reason for wanting to do this is just when you want to hide the implementation details so that the caller only sees a single opaque pointer.
======= OuterClass.h =====
class InnerClass; // forward declaration is all that's needed
class OuterClass {
private:
InnerClass *pInner;
public:
InnerClass();
bool doSomething();
};
======= OuterClass.cpp ======
#include "OuterClass.h"
#include "InnerClass.h"
OuterClass::OuterClass() :
pInner(new InnerClass())
{
}
bool OuterClass::doSomething()
{
return pInner->doSomething();
}
There actually is a way to do this without having to use classes. I had the same issue and here is a very simple solution:
Just put your private things into the .cpp file. Your header file will look something like this:
// These will be visible to everyone using this library
void function();
int someNumber = 2;
and your .cpp file:
void function() {
// whatever this function does
}
// This will be only visible to the library itself
static void secretFunction() {
doSomeSecretStuff;
}
static int PIN = 1234;
// Okay, if you write this Number into your library and expect it to be safe,
// then screw you, but at least no one will be able to access it with code
When calling the "public" functions from outside you now don't need any instance of that class anymore: Just place the library in the correct directory and include it, but you probably have already taken care of that) and call the functions by their names in the Lib.h file. In the instance of this example it would look something like this:
#include "Lib.h"
int main(int argc, const char * argv[]) {
function();
return 0;
}
Thanks to Edgar Bonet for helping me find this solution on the Arduino Stackexchange!
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.
i wrote this code but friend function is not working(foodmoney and hobbymoney are not declare in my friend function. where is my Error here ?
#include <iostream>
using namespace std;
class myBase
{
private:
int friendvar;
int foodmoney;
int hobbymoney;
public:
void setdata();
myBase(){friendvar=0;}
friend void caldata(myBase &mbo);
};
void myBase::setdata()
{
cout<<"Enter foodmoney :" ;cin>>foodmoney;
cout<<"enter hoobymoney:";cin>>hobbymoney;
}
void caldata(myBase &mbo)
{
mbo.friendvar=(foodmoney+hobbymoney)/2;
cout<<mbo.friendvar<<endl;
}
int main()
{
myBase baseobj;
baseobj.setdata();
myBase friends;
caldata(friends);
return 0;
}
mbo.friendvar=(foodmoney+hobbymoney);
should be
mbo.friendvar=(mbo.foodmoney+mbo.hobbymoney);
etc. etc.
Friend functions are not member functions, so they do not have special access to any particular object. You must specify which object you wish to access (by using mbo in your case).
Having said that I can't see any good reason why caldata is a friend function. Why not make it a regular member function? Or maybe you should make it a friend function with two arguments? It's hard to say what you're trying to achieve here.
change
cin>>foodmoney;
to
cin>>mbo.foodmoney;
and change
cin>>hobbymoney;
to
cin>>mbo.hobbymoney;
Your code doesn't compile at all. Fix is described already. But to make ti complete:
As you have referenced friendvar using mbo.friendvar, do the same for foodmoney and hobbymoney.
Also you have not initialized foodmoney and hobbymoney in your constructor. And in your call to caldata(friends); you are therefor getting random result printed on screen.
Last: you instantiate new object with myBase friends; so this is completely new object that is not affected by previous call of setdata().
Your low level requirements for this function are not defined in your question, I cannot help more.