I have learned that function name equals function address
like this:
void func(){}
void main() { cout << func; }
But when I used the same code to print memeber function, it went wrong.
class Test{
public:
void func() {}
void printFunc1() {
cout << func << endl;
}
void printFunc2() {
void (Test::*ptrtofn)() = &Test::func;
cout << (void*&)ptrtofn << endl;
}
};
printFunction2() work but printFunction1() doesnt
What makes the difference?
Member function's name is not member function's address?
Is there any reason?
member function != standalone function
Only standalone functions can be converted to pointer implicitely.
4.3 Function-to-pointer conversion [conv.func]
1 An lvalue of function type T can be converted to a prvalue of type “pointer to T.” The result is a pointer to the function. 58
58) This conversion never applies to non-static member functions
because an lvalue that refers to a non-static member function cannot
be obtained.
Please understand "func" is the member function of the class . accessing it directly is itself a compilation error .Rather you should try to use pointer to member function as you have done in printFunction2:
Else if func is function outside the class scope .Then it can be done as below :
#include <iostream>
using namespace std;
void func() {cout<<"\n calling func\n";}
void printFunc1() {
cout << endl<<hex<<(void*)func << endl;
}
int main() {
printFunc1();
return 0;
}
Related
I am having difficulty calling a pointer to a member function on an object that was cast from void*. See below example:
class Test
{
public:
Test(int pointTo)
{
if (pointTo == 1)
function = &Test::Function1;
else
function = &Test::Function2;
}
static void CallIt(void* cStyle)
{
Test* t(static_cast<Test*>(cStyle));
(t->*function)();// error C2568: '->*': unable to resolve function overload
}
void CallIt()
{
(this->*function)();// Works just fine
}
private:
typedef void (Test::*ptrToMemberFunc)();
ptrToMemberFunc function;
void Function1()
{
std::cout << "Function 1" << std::endl;
}
void Function2()
{
std::cout << "Function 2" << std::endl;
}
};
int main()
{
Test t1(1);
Test t2(2);
Test::CallIt(static_cast<void*>(&t1));
Test::CallIt(static_cast<void*>(&t2));
t1.CallIt();
t2.CallIt();
return 0;
}
What happens when the object is cast to void* and back? Why can I no longer call the pointer to member function?
EDIT:
Modifying CallIt() as follows allows the program to compile, but I'm still curious as to why the original didn't work.
static void CallIt(void* cStyle)
{
Test* t(static_cast<Test*>(cStyle));
Test::ptrToMemberFunc pf(t->function);
(t->*pf)();
}
main.cpp:17:14: error: invalid use of member 'function' in static member function
(t->*function)();// error C2568: '->*': unable to resolve function overload
^~~~~~~~
function is a non-static data member, so you cannot access it from a static function.
If you want to refer to t's function, you can do it like so:
(t->*(t->function))();
I know that the this pointer is implicitly passed to member functions when they are called. When I try to get the address of this pointer (via &this), though, I get the compiler error "lvalue required". Why is this?
class st
{
int a,b;
public :
void print()
{
cout << &this; //gives lvalue required... why?
cout << this; //will print address of object.
}
}
this is not an lvalue but an prvalue. From [class.this]:
In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. The type of this in a member function of a class X is X*. If the member function is declared const, the type of this is const X*, if the member function is declared volatile, the type of this is volatile X*, and if the member function is declared const volatile, the type of this is const volatile X*.
Emphasis mine
& requires an lvalue so you cannot get the address of this.
Because this pointer is a rvalue. this pointer is a constant value, it is passed to the member function like a local variable, so it's value is stored in a memory location that would become invalid when returning from that function.
Presumably you're trying to print out the values in the object. cout doesn't know how to do this, and you have to teach it.
cout << *this;
might do this if cout knew how to do it, but you can teach it. Here's an example that is more natural c++. (You should also consider a constructor).
#include <iostream>
using namespace std;
class st
{
public:
int a,b;
};
std::ostream& operator<<(std::ostream& s, const st& val)
{
return s << "a:" << val.a << " b:" << val.b ;
}
int main() {
st foo;
foo.a = 1;
foo.b = 2;
cout << "foo is " << foo << endl;
}
My program is not compiling and keeps outputing the same error "non-lvalue in assignment." I've tried looking around the internet to why this is happening but I can't seem to find anything. I would really appreciate some input.
#include <iostream>
using namespace std;
class Class
{
public:
Class()
{
Var=0;
}
private:
int Var;
friend void Friend(Class &object);
};
void Friend(Class &object)
{
&object.Var=99;
cout << &object.Var << endl;
}
int main()
{
Class testobject;
Friend(testobject);
}
You won't need the & inside the function
The problem is this line &object.Var=99; You taking the address of object and than accessing .Var, this cant work.
Seems you missunderstood references, you dont have to dereference them (unlike pointer).
Change your function to this:
void Friend(Class &object)
{
object.Var=99;
cout << object.Var << endl;
}
Change the function definition to
void Friend(Class &object)
{
object.Var=99;
cout << object.Var << endl;
}
The reason of the error is described in the following quote of the C++ Standard
if the type of the expression is T, the result has type “pointer to T”
and is a prvalue
Replace &object.Var=99; with object.Var=99; and cout << &object.Var << endl; with cout << object.Var << endl;
When passing an argument, & denotes that you receive the variable as a reference.
void Friend(Class &object) means you get the reference of testobject in object.
&object.Var implies address of object.Var. You cannot assign to that. Hence the error non-lvalue in assignment.
I'm fairly new to C++, and I don't understand what the this pointer does in the following scenario:
void do_something_to_a_foo(Foo *foo_instance);
void Foo::DoSomething()
{
do_something_to_a_foo(this);
}
I grabbed that from someone else's post on here.
What does this point to? I'm confused. The function has no input, so what is this doing?
this refers to the current object.
The keyword this identifies a special type of pointer. Suppose that you create an object named x of class A, and class A has a non-static member function f(). If you call the function x.f(), the keyword this in the body of f() stores the address of x.
The short answer is that this is a special keyword that identifies "this" object - the one on which you are currently operating. The slightly longer, more complex answer is this:
When you have a class, it can have member functions of two types: static and non-static. The non-static member functions must operate on a particular instance of the class, and they need to know where that instance is. To help them, the language defines an implicit variable (i.e. one that is declared automatically for you when it is needed without you having to do anything) which is called this and which will automatically be made to point to the particular instance of the class on which the member function is operating.
Consider this simple example:
#include <iostream>
class A
{
public:
A()
{
std::cout << "A::A: constructed at " << this << std::endl;
}
void SayHello()
{
std::cout << "Hi! I am the instance of A at " << this << std::endl;
}
};
int main(int, char **)
{
A a1;
A a2;
a1.SayHello();
a2.SayHello();
return 0;
}
When you compile and run this, observe that the value of this is different between a1 and a2.
Just some random facts about this to supplement the other answers:
class Foo {
public:
Foo * foo () { return this; }
const Foo * cfoo () const { return this; /* return foo(); is an error */ }
};
Foo x; // can call either x.foo() or x.cfoo()
const Foo y; // can only call x.cfoo()
When the object is const, the type of this becomes a pointer to const.
class Bar {
int x;
int y;
public:
Bar () : x(1), y(2) {}
void bar (int x = 3) {
int y = 4;
std::cout << "x: " << x << std::endl;
std::cout << "this->x: " << this->x << std::endl;
std::cout << "y: " << y << std::endl;
std::cout << "this->y: " << this->y << std::endl;
}
};
The this pointer can be used to access a member that was overshadowed by a function parameter or a local variable.
template <unsigned V>
class Foo {
unsigned v;
public:
Foo () : v(V) { std::cout << "<" << v << ">" << " this: " << this << std::endl; }
};
class Bar : public Foo<1>, public Foo<2>, public Foo<3> {
public:
Bar () { std::cout << "Bar this: " << this << std::endl; }
};
Multiple inheritance will cause the different parents to have different this values. Only the first inherited parent will have the same this value as the derived object.
this is a pointer to self (the object who invoked this).
Suppose you have an object of class Car named car which have a non static method getColor(), the call to this inside getColor() returns the adress of car (the instance of the class).
Static member functions does not have a this pointer(since they are not related to an instance).
this means the object of Foo on which DoSomething() is invoked. I explain it with example
void do_something_to_a_foo(Foo *foo_instance){
foo_instance->printFoo();
}
and our class
class Foo{
string fooName;
public:
Foo(string fName);
void printFoo();
void DoSomething();
};
Foo::Foo(string fName){
fooName = fName;
}
void Foo::printFoo(){
cout<<"the fooName is: "<<fooName<<endl;
}
void Foo::DoSomething(){
do_something_to_a_foo(this);
}
now we instantiate objects like
Foo fooObject("first);
f.DoSomething();//it will prints out first
similarly whatever the string will be passed to Foo constructor will be printed on calling DoSomething().Because for example in DoSomething() of above example "this" means fooObject and in do_something_to_a_foo() fooObject is passed by reference.
Acc. to Object Oriented Programming with c++ by Balaguruswamy
this is a pointer that points to the object for which this function was called. For example, the function call A.max() will set the pointer this to the address of the object. The pointer this is acts as an implicit argument to all the member functions.
You will find a great example of this pointer here. It also helped me to understand the concept.
http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/
Nonstatic member functions such as Foo::DoSomething have an implicit parameter whose value is used for this. The standard specifies this in C++11 §5.2.2/4:
When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument. [Note: Such initializations are indeterminately sequenced with respect to each other (1.9) — end note ] If the function is a non-static member function, the this parameter of the function (9.3.2) shall be initialized with a pointer to the object of the call, converted as if by an explicit type conversion (5.4).
As a result, you need a Foo object to call DoSomething. That object simply becomes this.
The only difference (and it's trivial) between the this keyword and a normal, explicitly-declared const pointer parameter is that you cannot take the address of this.
It is a local pointer.It refers to the current object as local object
It looks like std::cout can't print member function's address, for example:
#include <iostream>
using std::cout;
using std::endl;
class TestClass
{
void MyFunc(void);
public:
void PrintMyFuncAddress(void);
};
void TestClass::MyFunc(void)
{
return;
}
void TestClass::PrintMyFuncAddress(void)
{
printf("%p\n", &TestClass::MyFunc);
cout << &TestClass::MyFunc << endl;
}
int main(void)
{
TestClass a;
a.PrintMyFuncAddress();
return EXIT_SUCCESS;
}
the result is something like this:
003111DB
1
How can I print MyFunc's address using std::cout?
I don't believe that there are any facilities provided by the language for doing this. There are overloads for operator << for streams to print out normal void* pointers, but member function pointers are not convertible to void*s. This is all implementation-specific, but typically member function pointers are implemented as a pair of values - a flag indicating whether or not the member function is virtual, and some extra data. If the function is a non-virtual function, that extra information is typically the actual member function's address. If the function is a virtual function, that extra information probably contains data about how to index into the virtual function table to find the function to call given the receiver object.
In general, I think this means that it's impossible to print out the addresses of member functions without invoking undefined behavior. You'd probably have to use some compiler-specific trick to achieve this effect.
Hope this helps!
I'd like to add to the other answers, that the reason that you are getting '1' printed instead of an address, is that, for some reason, the compiler is coercing your function pointer into a boolean, so that you are really calling ostream& operator<< (bool val);
This seems to be unrelated to the function being a member function.
You can uncover this kind of information with clang++ -cc1 -ast-dump:
(ImplicitCastExpr 0x3861dc0 <col:13, col:25> '_Bool' <MemberPointerToBoolean>
(UnaryOperator 0x3861940 <col:13, col:25> 'void (class TestClass::*)(void)' prefix '&'
(DeclRefExpr 0x38618d0 <col:14, col:25> 'void (void)' CXXMethod 0x3861500 'MyFunc' 'void (void)')))))
One way to do that is (I'm not sure it's portable) :
void TestClass::PrintMyFuncAddress(void)
{
void (TestClass::* ptrtofn)() = &TestClass::MyFunc;
cout << (void*&)ptrtofn<< endl;
}
working example : http://ideone.com/1SmjW
Pointers to member functions need memory, too. They also have a size. So how about printing out the memory of the pointer:
template<typename R, typename T, typename... Args>
std::string to_string(R (T::*func)(Args...))
{
union PtrUnion
{
R(T::*f)(Args...);
std::array<unsigned char, sizeof(func)> buf;
};
PtrUnion u;
u.f = func;
std::ostringstream os;
os << std::hex << std::setfill('0');
for (auto c : u.buf)
os << std::setw(2) << (unsigned)c;
return os.str();
}
You can use it this way:
class TestClass
{
void foo();
};
...
std::cout << to_string(&TestClass::foo) << std::endl;