Invalid use of non-static member function c++ - c++

I am following this example. But when I compile, it returns an error:
Invalid use of non-static member function
at the line
void(Machine:: *ptrs[])() =
{
Machine::off, Machine::on
};
I tried to add static to void on(); at class
class Machine
{
class State *current;
public:
Machine();
void setCurrent(State *s)
{
current = s;
}
static void on(); // I add static here ...
static void off(); // and here
};
But it complains that
Invalid use of member Machine::current in static member function
Can you help me fix this?

Unlike static member functions or free functions, non-static member functions won't implicitly convert to member function pointers.
(emphasis mine)
An lvalue of function type T can be implicitly converted to a prvalue pointer to that function. This does not apply to non-static member functions because lvalues that refer to non-static member functions do not exist.
So you need to use & explicitly to take the address of the non-static member functions (i.e. to get non-static member function pointers). e.g.
void(Machine:: *ptrs[])() =
{
&Machine::off, &Machine::on
};
If you declare them as static member function, you should change the type of ptrs (to array of non-member function pointers). Note that for static member function it's fine to not use & explicitly. e.g.
void(*ptrs[])() =
{
Machine::off, Machine::on
};

Related

returning pointer to a function inline without typedef

I'm running into syntax errors with C++ where I have to return a pointer to a function inline.
struct Note{}
Observer.hpp
class Observer {
protected:
void (*notify)(Note *note); // should this be *(*notify...)?
public:
void (*(*getNoteMethod)())(Note *note);
};
Observer.cpp
void (*Observer::getNoteMethod())(Note*) { //error: non-static data member defined out-of-line
return this->notify;
}
I'm getting this error, error: non-static data member defined out-of-line
I'm new to C++ and attempting to define the return function signature correctly.
The problem is the declaration syntax for the member function (which returns function pointer). Declare it as:
class Observer {
protected:
void (*notify)(Note *note);
public:
void (*getNoteMethod())(Note *note);
};
Better to declare the function pointer type in advance via using or typedef, which looks much clearer. E.g.
class Observer {
using function_pointer_type = void(*)(Note*); // the function pointer type
protected:
function_pointer_type notify; // the data member with function pointer type
public:
function_pointer_type getNoteMethod(); // the member function returns function pointer
};
// Out-of-class member function definition
Observer::function_pointer_type Observer::getNoteMethod() {
return this->notify;
}

c++ : discards qualifier even if the member variables are mutable

I am having some issues with const/mutable and protected. Maybe these are confusing me a little bit so I will give an example.
class Base
{
virtual void foo() const ;
protected :
void bar( int y ){ d_x = y } ;
private :
mutable int d_x ;
}
So base class has as a virtual foo.
class Derived : public Base
{
void foo() const { bar(5); }
private :
mutable int d_x ;
}
so in my derived class I have implemented foo, which class bar which then writes to the private d_x.
I would assume is fine - but compiler says :
passing 'Derived' as 'this' argument of bar discards qualifier.
Why is that? I thought by using mutable I could make my member function to be const.
From inside a const qualified function (such as foo), you may only call other const qualified functions. And bar is a not a const qualified function.
The fact bar only touches d_x is immaterial. The mutability of d_x only means that a const qualified member function can modify it directly. And formally, bar is allowed to modify any member (if they were to exist).
Const member function foo calls non-const member function bar. Calling bar requires a non-const this, whereas this is a pointer to const inside foo.
Either bar must be const or foo must be non-const.

Can you put a function inside of another function in c++?

Say I have two functions, and one calls the other to work.
void friendList::addFriend(string userNameIn)
{
if(friendList::isFriend(userNameIn))
//add friend
}
bool friendList::isFriend(string name)
{
//check if user name exists
}
Is this allowed? I am getting errors for:
In member function 'void User::addFriend(std::string)':
and error: cannot call member function 'bool friendList::isFriend(std::string)' without object
Is it because the functions aren't completely filled out yet?
Yes, functions can of course call other functions in C++.
Doing so is not a case of functions being put inside other functions: your question title is misleading.
It looks as if addFriend might be a static member function, and as such it has no object, whereas isFriend is a non-static member function. When a static member function of a class calls a non-static member function, it must supply an object:
class someclass {
// ...
static void static_member();
void nonstatic_member();
};
void some_class::static_member()
{
nonstatic_member(); // error
some_instance.nonstatic_member(); // okay
}
void some_class::nonstatic_member()
{
}
static_member cannot call nonstatic_member, but it can invoke nonstatic_member on an object. It will work provided that some_instance is suitably defined somewhere as an instance of some_class.
The compiler error:
cannot call member function [...] without object
Suggests to me that you are trying to call a non-static member function directly, rather than through an object. For example:
class Foo
{
public:
int DoIt() {}
};
int main()
{
Foo::DoIt();
}
If that's what you're trying to do, you can't. Non-static member functions need to be called through an object:
int main()
{
Foo foo;
foo.DoIt();
}
If you must refrain from calling through an object, then you need to make the member function static:
class Foo
{
public:
static int DoIt() {}
};
int main()
{
Foo::DoIt(); // OK
}
But then, DoIt won't be able to call other non-static member functions.
You want to use the 'this' pointer. this->isFriend(userNameIn)

Pointer to member function for as argument for global function

There is such code:
void foo(void (*fun_ptr)()){
}
class B{
public:
B(){
foo(some_fun);
}
void some_fun(){}
};
Compilation error:
error: argument of type ‘void (B::)()’ does not match ‘void (*)()’
How to point to member function in this case? I cannot change declaration of function foo, only class B!
Declare B::some_fun() as static as there is an implicit this pointer passed as an argument to member functions. Note that making B::some_fun() static prevents access to non-public non-static members of B.
This a FAQ in it's own right.
There is no other solution than to wrap the member function in a static function and somehow tell it about the object instance to invoke the method on:
struct X { void foo(); }
void take_callback(void (*fun_ptr)())
{
fun_ptr(); // invoke callback
}
//wrap the method
X* instance = 0;
void wrap_memberfun()
{
if (instance) instance->foo(); // delegate
}
int main()
{
X x;
take_callback(&X::foo); // doesn't compile
// workaround:
instance = &x;
take_callback(&wrap_memberfun);
}
some_fun() is a member function and needs an object. Make some_fun() static.
static void some_fun() {};
To invoke non-static member function you need two pointers (function and class instance), so you can't really use pointer to a non-static member where you expect pointer to a function.

quick question about static function in c++

static function in c++
SO, there can be only one instance of static function for this class. Right?
In C++, a static member function is just like a normal, global function, except with respect to visibility of names:
The name of the function is qualified with the class name.
Like a friend function, a static member function has access to private and protected class members. Also like a friend function, however, it does not have a this pointer, so it only has access to those parts of objects to which you've given it access (e.g., passed as a parameter).
(Thanks Alf): You can't declare any member function (static or otherwise) as extern "C".
A static member function (inside a class) means that you can call that function without creating an instance of the class first. This also means that the function cannot access any non-static data members (since there is no instance to grab the data from).
e.g.
class TestClass
{
public:
TestClass() {memberX_ = 10;}
~TestClass();
// This function can use staticX_ but not memberX_
static void staticFunction();
// This function can use both staticX_ and memberX_
void memberFunction();
private:
int memberX_;
static int staticX_;
};
Making a function static allows it to be called without instantiating an instance of the class it belongs to. learncpp.com has some more on the subject and check out the following example which will fail to compile:
class Foo
{
public:
static void Bar1();
void Bar2();
};
int main(int argc, char* argv[])
{
Foo::Bar1();
Foo x;
x.Bar2();
Foo::Bar2(); // <-- error C2352: 'Foo::Bar2' : illegal call of non-static member function
return 0;
}
Static functions can be called without actually creating a variable of that type, e.g.:
class Foo
{
public:
static void Bar();
void SNAFU();
};
int main( void )
{
Foo::Bar(); /* Not necessary to create an instance of Foo in order to use Bar. */
Foo x;
x.SNAFU(); /* Necessary to create an instance of Foo in order to use SNAFU. */
}