In the header file of class Class1, I've declared a function pointer fn_ptr and a function called myfunc(int,int):
class Class1
{
private:
bool (*fn_ptr)(int,int);
public:
Class1(); //Default Constructor
bool myfunc(int,int);
};
I want to have fn_ptr point to Class1's myfunction defined like so in the class's library file:
Class1::Class1()
{
fn_ptr = myfunc; //Initialization in the
}
Class1::myfunc(int a, int b)
{
return a<b;
}
Compiling resulted in an error:
error: argument of type 'bool (Class1::)(int,int)' does not match 'bool (*)(int,int)'
As user4581301 wrote in the comment, once you have a (non-static) member function, it takes a "hidden" pointer to the class's object, so you can't do directly what you tried here - the interfaces just don't match.
Also, there are currently more convenient facilities for function indirection that bare pointers.
Suppose you do the following. First, declare the class like this:
#include <functional>
using namespace std;
class Class1
{
private:
std::function<bool(int, int)> fn;
public:
Class1(); //Default Constructor
bool myfunc(int,int){ return true; }
};
Note how the member fn is of type std::function, which is more convenient and versatile.
Now in the constructor, you can simply initialize it with a lambda function:
Class1::Class1() :
fn([this](int i, int j){return myfunc(i, j);})
{
}
It says that for any i and j, just call myfunc (on this objet) on these arguments, and return the result.
Full code
Make sure to build using c++11 settings.
#include <functional>
using namespace std;
class Class1
{
private:
std::function<bool(int, int)> fn;
public:
Class1(); //Default Constructor
bool myfunc(int,int){ return true; }
};
Class1::Class1() :
fn([this](int i, int j){return myfunc(i, j);})
{
}
int main()
{
Class1 c;
}
In addition to #Ami's excellent answer about using std::function instead, member function pointers have different syntax, which is why it didn't work for you.
bool (Class1::*fn_ptr)(int,int); //note the Class1::
fn_ptr = &Class1::my_func; //the &Class1:: is necessary, forgetting it is a compilation error
Calling it is different, too. It needs an instance of the class to be called on.
Class1 c;
(c.*fn_ptr)(1, 2); //or (this->*fn_ptr) too
Related
I created a class and I want to force anyone who's trying to construct an object, to use unique_ptr. To do that I thought of declaring the constructor protected and use a friend function that returns a unique_ptr. So here's an example of what I want to do:
template <typename T>
class A
{
public:
friend std::unique_ptr<A<T>> CreateA<T>(int myarg);
protected:
A(int myarg) {}
};
template <typename T>
std::unique_ptr<A<T>> CreateA(int myarg)
{
// Since I declared CreateA as a friend I thought I
// would be able to do that
return std::make_unique<A<T>>(myarg);
}
I did some reading on friend functions and I understood that a friend function provides access to private/protected members of an object of a class.
Is there anyway I can make my example work?
Even without friend functions, my goal is to make the CreateA the only way for someone to create an object.
EDIT
I change the code a bit. I didn't mention that my class takes one template parameter. That makes things more complex apparently.
You can do it this way :-
#include <iostream>
#include <memory>
using namespace std;
class A
{
int arg;
public:
friend unique_ptr<A> CreateA(int myarg);
void showarg() { cout<<arg; }
protected:
A(int myarg): arg(myarg) {}
};
unique_ptr<A> CreateA (int myarg)
{
return std::unique_ptr<A>(new A(myarg));
}
int main()
{
int x=5;
unique_ptr<A> u = CreateA(x);
u->showarg();
return 0;
}
Output :-
5
If you don't want to use friend function you can make the function static & call it like this :-
unique_ptr<A> u = A::CreateA(x);
EDIT :-
In reply to your edit I rewrote the program & it goes like this :-
#include <iostream>
#include <memory>
using namespace std;
template <typename T>
class A
{
T arg;
public:
static std::unique_ptr<A> CreateA(T myarg)
{
return std::unique_ptr<A>( new A(myarg) );
}
void showarg()
{
cout<<arg;
}
protected:
A(T myarg): arg(myarg) {}
};
int main()
{
int x=5;
auto u = A<int>::CreateA(x);
u->showarg();
return 0;
}
Simple & easy !!! But remember you cannot instantiate the object of A. Good Luck !!!
The other answers suggest using a static template function, which I agree is the best solution, because it is simpler.
My answer explains why your friend approach didn't work and how to use the friend approach correctly.
There are two problems in your original code. One is that make_unique is not actually a friend of A, so the call make_unique<A<T>>(myarg); does not have access to A's protected constructor. To avoid this , you can use unique_ptr<A<T>>(new A(myarg)) instead. Theoretically it would be possible to declare make_unique a friend but I'm not even sure of the right syntax for that.
The other issue is the template friends problem. Inside a class template, friend <function-declaration> actually declares a non-template friend.
The C++ FAQ suggests two possible workarounds. One of them is to define the friend function inline. However, in that case the function can only be found by argument-dependent lookup. But since the function does not take A<T> (or A<T> &) as argument, it can never be found this way. So this option is not viable to your situation -- it's more suited to operator overloading.
So the only fix is to declare (and optionally define) the template function before the class definition:
#include <memory>
template<typename T>
class A;
template <typename T>
std::unique_ptr<A<T>> CreateA(int myarg)
{
return std::unique_ptr<A<T>>{new A<T>(myarg)};
}
template <typename T>
class A
{
friend std::unique_ptr<A<T>> CreateA <> (int myarg);
// refers to existing template ^^
protected:
A(int myarg) {}
};
int main()
{
auto x = CreateA<int>(5);
}
Note: It is possible to declare CreateA where I have defined it, and put the function definition later. However, the code I have posted works -- despite A not being defined when new A<T>(myarg) appears in the source -- because CreateA is not instantiated until it is called, at which point A will be defined.
Create a static function that instantiates the protected constructor.
#include<iostream>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include <memory>
using namespace std;
template< typename T >
class A
{
public:
static void CreateA(int myarg, std::unique_ptr<A<T>>& objA, T t) {
std::unique_ptr<A<T>> objB(new A(myarg, t));
objA = std::move(objB);
}
protected:
A(int myarg, T t) {
m_t = t;
}
private:
T m_t;
};
int main() {
int myArg = 0;
std::unique_ptr<A<int>> anotherObjA;
A<int>::CreateA(myArg, anotherObjA, myArg);
return 0;
}
How could I make a function only seen by the function that calls it?
define the function I want to hide as private function is not enough, as it could still be seen by other public functions in the class.
Now I use lambda expression to define anonymous function inside function. Is there any better solution?
Aside from using a lambda (which you've rejected), you could implement your function in its own compilation unit, and code the supporting function in an anonymous namespace within that compilation unit.
But that supporting function would be outside the class, so you'd have to pass it all the parameters it needed. That could become unwieldly though no worse than a long lambda capture list.
You can use a function object. For example(you can compile this, even in C++03):
#include <iostream> // only for output
class foo{
int bar(){return 0;} // Only foo can see this
public:
int operator()(){
return bar();
}
};
class baz{
public:
foo do_foo;
};
int main(){
baz a;
std::cout << a.do_foo() << std::endl;
}
the method bar is only visible by a foo.
P.S.: If you need foo to access members of baz, make it a friend.
A simmilar approach to cassiorenan would be to use static class functions and friends.
Something like this:
void Boss();
class Worker {
static void Test(){ return;}
friend void Boss();
};
void Boss(){
Worker::Test();
}
Though why would you want to do this, I don't know.
It is possible to define function inside a function without lambdas. Just define a struct that contains required function. This approach is not much better than using lambda, but at least this is straightforward and works with older compilers too.
int func() {
struct {
int hiddenFunc() {
return 1;
}
} h;
int a = h.hiddenFunc() + h.hiddenFunc();
return a;
}
As a slight variation from cassiorenan's solution, you could use a class containing one public static function (the visible function) and one static private function that could only be called from there. To avoid creation of objects of that class, it is enough to put a private constructor.
EDIT:
Per cassiorenan's comment, I can see that OP really needs methods and not functions. In that case, I would still use a dedicated class in a anonymous namespace to ensure it is not visible from elsewhere (even if my example is single file ...) friend to the class really used. So in below example, bar is the business class that would have a method with an externally hidden implementation (here relay_method), and foo is dedicated to the hidden method called with a pointer to the real object. In real world, the whole anonymous namespace and the implementation of the hidden method should be in the implementation file bar.cpp.
That way, the real implementation function priv_func can only be called from a bar object through bar::relay_method() and foo::bar_func(bar &).
#include <iostream>
class bar;
namespace {
class foo {
private:
static int priv_func(int i) {
return i * i;
}
foo() {}
public:
// only useful if true functions were needed
/* static int pub_func(int i, int j) {
return priv_func(i) + priv_func(j);
}*/
static void bar_func(bar& b);
};
}
class bar {
int x;
int x2;
public:
bar(int i): x(i) {}
void relay_method() {
foo::bar_func(*this);
}
friend class foo;
int getX2() const {
return x2;
}
};
void foo::bar_func(bar& b) {
b.x2 = foo::priv_func(b.x);
}
using namespace std;
int main() {
/* int i = foo::pub_func(3,4);
cout << i << endl;
// foo::priv_func(2); error access to private member of class foo
// foo f; */
bar b(2);
b.relay_method();
cout << b.getX2() << endl;
return 0;
}
I have a member function in class B and class D that calls the function 'computeValue' which is not a member function of any class. The 'computeValue' function performs some type of algorithm and returns a value. However it seems like I'm getting a lot of compilation errors and not sure what the underlying reasons are. Is it even possible for member functions of classes to call non-member functions?
#include<iostream>
using namespace std;
int computeValue(vector<A*>ex) //Error - Use of undeclared identifier 'A'
{
//implementation of algorithm
}
class A
{
};
class B
{
int sam2()
{
return computeValue(exampleB); // Error - No matching function for call to 'computeValue
}
vector <A*> exampleB;
};
class D
{
int sam1 ()
{
return computeValue(exampleD);// Error - No matching function for call to 'computeValue
}
vector<A*> exampleD;
};
int main()
{
}
computeValue needs the declaration of class A, so declare A before it:
class A
{
};
int computeValue(vector<A*>ex)
{
//implementation of algorithm
}
Is it even possible for member functions of classes to call non-member functions?
Of cource, yes.
Yes, definitely you can call class non-member function from class.
Here you are getting errors because of mainly two issue:
You are using vector but you haven't declared vector header file in your code.
#include<vector>
You are using class A pointer as a parameter to function "computeValue" which is defined before the class A.
So either define class A before function or use forward declaration concept.
Here is error free modified code:
#include<iostream>
#include<vector>
using namespace std;
**class A; //forward declaration of Class A**
int computeValue(vector<A*> ex) //Error - Use of undeclared identifier 'A'
{
//implementation of algorithm i
return 5;
}
class A
{
};
class B
{
int sam2()
{
return computeValue(exampleB); // Error - No matching function for call to 'computeValue
}
vector <A*> exampleB;
};
class D
{
public:
D()
{
cout<<"D constructor"<<endl;
}
int sam1 ()
{
return computeValue(exampleD);// Error - No matching function for call to 'computeValue
}
vector<A*> exampleD;
};
int main()
{
D d;
}
This code will give you output: "D constructor"
I hope this will help you.
I've got a namespace MyNamespace containing a class MyClass with many static public members functions.
What I need to do, is to build, inside the namespace, a map containing a pointer on every public members functions of the class
Here the code:
#include <iostream>
#include <map>
namespace MyNamespace {
class MyClass;
typedef bool (*fctPtr)(void);
typedef std::map<std::string, fctPtr> fctMap;
};
class MyNamespace::MyClass {
public:
static bool func1(void) { return true; };
static bool func2(void) { return true; };
static bool func3(void) { return true; };
static bool func4(void) { return true; };
};
MyNamespace::fctMap MyFctMap;
void execFct() {
MyNamespace::MyClass obj;
MyNamespace::fctPtr fctMemb;
fctMemb = MyFctMap["func1"];
(obj.*fctMemb)();
}
int main() {
MyFctMap["func1"] = &MyNamespace::MyClass::func1;
MyFctMap["func2"] = &MyNamespace::MyClass::func2;
MyFctMap["func3"] = &MyNamespace::MyClass::func3;
MyFctMap["func4"] = &MyNamespace::MyClass::func4;
execFct();
}
And what the compiler says:
% clang++ draft.cc
draft.cc:29:7: error: right hand operand to .* has non pointer-to-member type
'MyNamespace::fctPtr' (aka 'bool (*)()')
(obj.*fctMemb)();
^ ~~~~~~~
1 error generated.
I don't understand why I got this error neither what to do to resolve the problem. Idea?
Edit: I'm using c++98 and no boost.
Working with a typedef bool (MyClass::*fctPtr)(void) drives me to this kind od error, at map assignment time.
error: assigning to 'mapped_type' (aka 'bool (MyNamespace::MyClass::*)()') from
incompatible type 'bool (*)()'
MyFctMap["func1"] = &MyNamespace::MyClass::func1;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since the functions you are referencing are static, you don't need the obj class reference. Simply call fctMemb();. You might also consider if you need these functions mapped in such a way, oftentimes you don't need that dynamic aspect to function references in C++ and instead should be using templates.
A pointer to a function is not the same as a pointer to a member function. The important thing to remember is that all (non-static) member function actually have a hidden first argument which is what becomes the this pointer. Therefore a function pointer and a member function pointer can't ever be compatible.
However, you should look into std::function and std::bind:
namespace NyNamespace
{
typedef std::function<bool()> fctPtr;
...
}
MyNamespace::MyClass myObject;
MyFctMap["func1"] = std::bind(&MyNamespace::MyClass::func1, myObject);
The idea is fctMemb(); :-)
fctPtr, as the compiler says, is not a pointer to member type...
Static member functions are not like normal member functions. They have access to class private and protected members, but they are not tied to object instances and thus can't access this pointer nor any non-static members.
Their type is that of normal function pointers and they can't be bound to member function pointers (and normal function pointers is what you have in your code).
You call them like normal functions:
fctMemb();
Btw, the sytax to form member function pointers is different:
struct Foo {
void f() {}
};
void (Foo::* mem_fun_ptr)() = &Foo::f;
Alright, I just thought give C++ a try (I currently do C#), now my first problem is class instantiating or calling a method in another class.
Here is my code:
My main Program entry:
#include <iostream>
#include "myClass.h"
using namespace std;
int main()
{
myClass* mc = new myClass();
}
The Class I'm trying to access:
#include "myClass.h"
myClass::myClass()
{
void DoSomething();
{
}
}
myClass::~myClass()
{
}
The Class Header:
#pragma once
class myClass
{
public:
myClass();
~myClass();
};
Now as you can see i have instantiated the class, but i cant access DoSomething() method.
This code simply declares a local function, and has an empty scope for fun:
myClass::myClass()
{
void DoSomething(); // local function declaration
{
// empty scope
}
}
If you want doSomething() to be a member of myclass, you have to declare it in the class definition:
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
then implement it
void myclass::doSomething() { .... }
Also note that you don't have to use new everywhere in C++. You can instantiate an object like this:
int main()
{
myClass mc;
}
Also note that using namespace std; isn't such a great idea anyway, at least not in real code.
this is a function declaration in a constructor (+an ampty scope within { }).
myClass::myClass()
{
void DoSomething();
{
}
}
You want a function declaration in class body (not in constructor) and definition of this function (this can be done immediately together with declaration or later as i.e. here):
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
implementation of constructor:
myClass::myClass() { .... }
implementation of your function, similarly:
void myClass::doSomething() { .... }
The method you are trying to use in main must be part of the class definition. You can write an inline function or can have a separate definition of that function. Also, you need to make that function public in order to access it from main.