Passing member function to function pointer - c++

I have to pass in a function pointer of a member function to another class. I couldn't get it to compile and I get the "undefined reference to classB::classB(classA::*)(std::shared_ptr) " error. Can someone help me with this?
Thanks.
classA{
string functionA(share_ptr<int>);
void functionB(){
classB* ptr = new classB(&classA::functionA);
}
}
//in other .h file
classA; //forward declaration
classB{
classB(string (classA::*funcPtr)(shared_ptr<int>); //constructor
}

Your code as I'm writing this:
classA{
string functionA(share_ptr<int>);
void functionB(){
classB* ptr = new classB(&classA::functionA);
}
}
Here:
share_ptr should be shared_ptr.
There is a missing semicolon at the end of the class definition.
Then,
//in other .h file
classA; //forward declaration
classB{
classB(string (classA::*funcPtr)(shared_ptr<int>); //constructor
}
Here:
There are three left parentheses ( but only two right parentheses ).
A semicolon is missing at the end of the class definition.
You're asking about a linking error, but your code should not even compile.
When you state "I couldn't get it to compile" that seems to be correct.
When you then state "I get [undefined reference to...]", well that's a mystery: with the toolchain that you're evidently using, the linker shouldn't be invoked when the compilation fails.
In summary, this question contains some incorrect information and any answer (such as the hypothesis that you haven't defined the function, or the hypothesis that you defined it somewhere but forgot to link in that, or the hypothesis that you're reporting errors from building something else than your code, so on) would be pure guesswork.
Please post a complete small program that compiles and illustrates the linking error.
Cheers & hth.,

Just for giggles, going to answer this even though you said it compiled for you ...
// In a.hpp
#include "b.hpp" // you need to include this because you will not
// be able to call B's constructor in your functionB() method
class A
{
public:
string functionA ( shared_ptr<int> ); // IIRC, needs to be public to call it
// from B's constructor.
// can be public/protected/private depending on where it's called ...
void functionB () {
B * ptrB = new B ( &A::functionA );
}
};
and
// In b.hpp
// Forward declare class A
class A;
// To make the constructor of B cleaner, use a typedef.
typedef string (A::*IntPtrToStrFn) ( shared_ptr<int> );
class B
{
public:
B ( IntPtrToStrFn fnptr );
};
As far as style and code readability goes, this is horrible - ties the two classes together and reaks of code smell. Need to look at some kind of adapter class or other design pattern to get the two classes to work together.

On the surface, this just looks like a forward declaration issue. Try declaring classA::functionB as you've done, and then defining classA::functionB after the definition of classB.

Related

c++ object of one class wants to use method of object in another class

I'm converting my old c++ program into OOP and as things grow bigger I'm splitting it per class in .h and .cpp files. The first class compiled nicely into an object file. But my second class is dependant on that first class and now I run into problems. Here my very simplified "all in a single file" code that works:
class A {
public:
void amethod(int) {
....code....
}
};
A a_obj; //object creation
class B {
public
void bmethod(void) {
a_obj.amethod(int);
}
};
B b_obj; //object creation
main() {
b_obj.bmethod();
}
After deviding the code over different files my .h files look like:
//file A.h:
class A {
public:
void amethod(int);
};
//file B.h
#include "A.h"
class B {
public
void bmethod(void);
};
In the implementation of class B there is the call to a_obj.amethod() and even I understand that g++ has no way to know that a_obj is an object of class A as I did not even include the a_obj object creating anywhere in the code.
How to solve this ? Is it something simple that I need to put the object creation somewhere in my .h or .cpp file (note that lots of other classes are using the same amethod()). I can not make everything static as I also have classes with multiple objects (in fact the same way of working is all over the program). Or is this way of working completely wrong (which would explain why I can not find any solution for this).
Is suggest you put more efforts in defining your interfaces.
If class B needs an instance of A to work, use parameters to pass an A:
class B {
public
void bmethod(A & a_obj) {
a_obj.amethod(int);
}
};
main() {
A a_obj;
B b_obj;
b_obj.bmethod(a_obj);
}
The problem is that your original code uses global data (i.e. the declarations of a_obj and b_obj are global). Globals are generally a bad idea because they can cause several problems. The 'proper' OOP way to do it would be to instantiate those objects in main(), and pass them to whatever other objects need to access them. You could pass references, pointers, or copies, depending on your needs.
With that said, if you really want to continue doing it with global data, then you can use an extern declaration. In each *.cpp file where you access a_obj, include this:
extern A a_obj;
That basically tells the compiler that there is an object with that name, but it exists somewhere else. I really don't recommend this approach if you're serious about learning OOP though.
I guess you are planning to use a_obj as global variable in other implementation file (.cpp).
So in header file B.h type extern reference to this instance.
extern A a_obj;
This declaration should help compile your B.cpp file. And ask actual instance a_obj during linking.
I didnt try this code, but telling by my experience and my practice(way) of coding. Hope this solution helps, else am sorry.
First, in order to call A::amethod() class B needs the full definition of class A and its amethod(). So you need to #include A.h before B.h in your .cpp files.
Next, if you address concrete a_obj object, you need to specify what that object is in order to link properly. In you first variant it was global object, so if it is what intended you can write: in A.cpp:
A a_obj;
in B.cpp:
extern a_obj;
// here you can call a_obj methods
But if these classes are so related that one calls methods of another, and also as I catched you need several objects of A and B, consider to connect these classes through inheritance:
class B : public A {
public:
void bMethod(int n) {
aMethod(n); // base class method call
}
// ...
or through delegation:
class B {
A m_A;
public:
void bMethod(int n) {
m_A.aMethod(n);
}
// ...
As mentioned earlier the way
void bMethod(A& a) {
a.aMethod();
}
will work, but the language has built-in means to express classes relationships.
How to implement is more design question, you can read more about this in Stroustrup 3rd edition, '24.3.5 Use Relationships'.
In C++ you can also pass a pointer to a member function of one class into the member function of another class to call a method from completely unrelated class (say, some callback), you can use boost::function and boost::bind for this. But it is advanced technique.

C++ Passing a pointer (pointing to an object) to function in another class

I need to pass a pointer which points to an instance of a class into a function which is inside another class so that the function can access some of the public variables of the first class.
Although i am not new to C++ this is the first time i have used pointers in this way and so i don't quite understand how to make this work.
What i have already done is similar to the following:
class foo
{
public:
int data;
};
class bar
{
public:
void function(foo *ptr); //error points to this line
};
void bar::function(foo *ptr)
{
ptr->data = 1; //do something with data inside foo class.
}
main()
{
foo foo1; //init foo as foo1.
foo *ptr_foo; //pointer of type foo called ptr_foo
prt_foo = &foo1; //point ptr_foo to the address of foo1
bar bar1; //init bar as bar1
bar1.function(ptr_foo) //call function1 and pass the address of our instance of foo to it.
}
Im getting errors from class bar saying "syntax error: identifier 'foo'" on the line defining function(foo *ptr).
I'm also getting the error "'bar::function': function does not take 1 arguments" when trying to call function(foo ptr*) in main(), I believe that's linked to the first error yes?
In the program i am working on foo(), bar() and main() are all in different source files linked with header files. does this contribute to my problem?
I'm finding pointers in this context difficult to understand and no amount of reading is helping with this particular problem.
If someone could tell me how to make this work that'd be great, an explanation of whats going on in the solution given solution and why what i have done doesn't work would be even better.
Thanks for any help.
EDIT:Code above is not intended to compile. My actual code is a lot larger than i could reasonably post.
If foo and bar are in separate headers, add forward declaration in bar before the bar class declaration:
class foo;
The code you've posted compiles, once the obvious typos are fixed.
Perhaps, in your real code, bar.h doesn't forward declare class foo; so there is no declaration of foo as the compiler says. You'll need to do that, or perhaps include the full definition of foo if the header needs to do anything complicated with it.
Or perhaps foo.h and bar.h both include try to include each other, which is impossible. If that's the case, it should be possible to remove one or both inclusions, replacing them with forward declarations if needed.
If none of this helps, then try to reduce your code to a simple test case which does reproduce the error. If you don't discover the cause of the problem when you do that, then you'll have a good test case to post here.
The error suggests that the file which defines class bar doesn't know about class foo. You need to #include the header file for class foo before your definition for class bar.
There is nothing wrong with the code you have written. There is a typo in your example code, prt_foo = &foo1; should be ptr_foo = &foo1;, but other than that it should work. You don't have to take the pointer to the class foo as a separate line. These lines in the main code will work:
foo foo1;
bar bar1;
bar1.function(&foo1);

What does the statement class foo; mean

I have been going through the code of a project and have encountered the statement
class foo;
.
.
.
.
foo* f1;
in various places. The class has not been declared in any of the headers included either. Can anybody tell me what that means.
It is a forward declaration. It can be used for classes, structs and functions, and it tells compiler that this is defined elsewhere or later.
For classes, there are (at least) two use cases.
1. Full definition not needed
After forward declaration, compiler does not know size or members of class, only name. That is enough for pointers to the class (and references which are basically syntactic sugar around pointers). But often pointer is enough, and then you can avoid including entire header file in another. This helps compilation speed, by avoiding need to recompile everything when one header changes.
myfuncs.h
class MyClass; // forward declaration
void helpMyClass(MyClass &needy);
// here this would give compiler error about incomplete type:
//void badHelp(MyClass needy); // value needs definition
myfuncs.cpp:
#include "myclass.h" // entire MyClass definition
void helpMyClass(MyClass &needy) {
needy.helpMe(false); // needs full definition
}
Important use case for this is the so called PIMPL idiom, also well covered here at SO under pimpl-idiom tag.
2. Two classes need to refer to each others
class node; // forward declarion
class collection {
node *frist; // pointer enabled by forward declaration
}
class node {
collection *owner; // already defined above so works too
}
In this case forward declaration is required to make this work nicely. Just saying in case you see it in the wild, there's the ugly way of using void pointer and casts, sometimes used when novice programmer does not know how this should be done.
I think you're referring to a forward declaration. It tells the compiler that a class named foo will be defined later. Until then it is an "incomplete type", meaning that pointers and references to the class can be defined. Instances of the class cannot be created until it is fully defined.
Your declaration is incorrect? I'm not sure.. I do know that you can't have "any" space "name".. Perhaps you missed an underscore?
I believe you meant:
class foo any_name();
In that case, it's forward declaring a function called any_name that returns a class instance of foo.
Example:
#include <iostream>
class foo any_name(); //The forward declaration..
class foo //the foo class implementation.
{
public:
foo(){std::cout<<"hey";}
};
class foo any_name() //The implementation of the function..
{
std::cout<<"any_name";
//return {}; //Can be used to return a constructed instance of foo.
};
int main()
{
any_name();
}

Resolving Inclusion Ordering

I am working on a codebase that is not my own, that has the following layout:
object.h:
// Objects are defined
// #include "tickets.h" (functions to access the objects)
// An access-handler object is defined
I want to introduce a class that knows about the objects, can be accessed from functions in tickets.h, but can also use the access-handler object. The functions are separate, i.e. class functions that are called in tickets.h do not use the access-handler (I wouldn't know where to start if that weren't the case).
Therefore my class needs to be defined before tickets.h, but some of its functions need to be defined after the access-handler. Is there a way to do this without splitting it up into two header files something like the following:
// Objects are defined
// -- include declaration of class, and definition of functions that tickets.h needs
// #include "tickets.h"
// An access-handler object is defined
// -- include functions of class that need the access-handler
This seems very messy splitting things up like this into two separate files, I was hoping to keep everything contained.
Thanks for any help, I clearly only have a very rudimentary understanding of declarations/definitions in c++.
EDIT: If I use forward declaration and include it before tickets.h (with the class declared in mynewclass.h and functions defined in mynewclass.cc) will mynewclass.cc be able to use objects declared after the inclusion of mynewclass.h? Namely the access-handler object.
EDIT2: Something like this:
object.h:
class obj { // definition }
#include "tickets.h"
class obj_handler {
public void handle { // code }
}
tickets.h:
void do_something(obj o){
communicator.foo();
}
My object (communicator):
class communicator {
public:
void foo() { // code }
void bar() { // use handle() from obj_handler }
}
As you can see, my communicator needs to be used in tickets.h, but can't be defined until after obj_handler. So where should I include it?
If I correctly understand your question - you can use forward declaration to solve this problem. This will allow you to declare some class before defining it's methods. For example:
// this is forward declaration of class A, no definition provided
class A;
class B
{
// uses A
A * a_;
};
// class A definition
class A
{
// may use class B now
B * b_;
};
I'm not quite sure whether I understand this right and don't have enough reputation here yet to make this a comment, so let me try to answer your question this way, please feel free to follow up if I'm guessing wrong:
I believe what you are referring to is an entire class definition, i.e., one including all function definitions within the class declaration. Other than that, it is not very common to see object definitions followed by preprocessor directives. What is typical though is a forward declaration of functions and a class prototype.
So, for example, you could declare in some header.h:
class C
{
public:
void method1(void);
int method2(void);
};
And in some implementation.cpp the definition of the functions like:
void C::method1(void) { /*...*/ }
In the other file preceded in the inclusion chain by your access-handler you then define the other function:
int C::method2(void) { /*...*/ }
What do you mean by access-handler, by the way?
Oh, and your linker likely will yell somewhat at you if you do function definition in a header file.
With regard to your addenda: everywhere you put a forward declaration, loosely speaking, the compiler will insert a copy of the declaration in question, consider it a soft link in the context of file systems. There are negative implications associated with it, like increased duration and the memory load of compilation if you have many forward declarations of the function signature or class. It's impossible to tell whether this will word in your particular situation since only you know the actual code in question. But most likely it would work.
Take a look at these pages:
http://en.wikipedia.org/wiki/Forward_declaration
When can I use a forward declaration?

C++ - .h and .cpp

If I have a .h file that contains the following for example:
class A
{
...
}
Notice that there is no customized constructor here.
Now, in the .cpp file, can I write the following:
A
{
...
}
In other words, is it ok not to use a constructor after the class name as follows?
A::A()
{
...
}
Thanks.
If your question is whether or not you can use A{} to define a constructor, no, you need to use A::A(){...} syntax for the constructor if you are defining it in the cpp file.
If you are asking if you don't need a constructor, no, you don't necessarily need one, the compiler will supply you with a default.
I should say that if you are doing the constructor in the class definition you can use A(){...}, such as
class A
{
public:
A(){}
};
I believe the answer to your question is "No". But it's kind of a confusing question. The syntax you propose for the contents of the .cpp file is demonstrably uncompilable.
is it ok not to use a constructor after the class name
As classes get longer and more complicated, mixing the definition and the implementation details makes the class harder to manage and work with.
Traditionally, the class definition is put in a header file of the same name as the class, and the member functions defined outside of the class are put in a .cpp file of the same name as the class.
No. Once you've defined class A like that, the compiler expects A to start one of
A MyObject;
A MyOtherObject = { /* initial values */ }; // C style since there's no ctor
A MyFunction();
A MyFunction() { return MyObject; }
or perhaps a variation like
A* MyPointer;
A& MyReferemce = MyObject;
As you see, the compiler expects you declare something after A. But you have A {. That's just not right: you started a declaration, but you never named what you're declaring.
Yes You Can.If i understood your question correctly.
HEADER FILE
#include &lt iostream&gt
using namespace std;
class A{
public:
A();
void func();
};
CPP FILE
#include "h.hpp"
using namespace std;
A::A(){cout &lt&lt "Constructor" &lt&lt endl;}
int main(){
A a;
return 0;
}