Pointer to class data member question

W

WaterWalk

Hello. I am rather confused by the type of a pointer to class data
member. Many c++ texts say that pointer to data member has a special
syntax. For example the following class:
class MyClass
{
public:
int n;
};

The pointer to MyClass.n shall be defined like this:
typedef int MyClass::*pn_t;
pn_t pn = &MyClass::n
MyClass my;
my.*pn = 1;

But at the same time, the following code also works:
MyClass my;
int *pn = &my.n;
*pn = 1;

So I wonder if the second method is legal in the c++ standard. If it
is, why bother to have the first method?
 
B

Barry

WaterWalk said:
Hello. I am rather confused by the type of a pointer to class data
member. Many c++ texts say that pointer to data member has a special
syntax. For example the following class:
class MyClass
{
public:
int n;
};

The pointer to MyClass.n shall be defined like this:
typedef int MyClass::*pn_t;
pn_t pn = &MyClass::n
MyClass my;
my.*pn = 1;

But at the same time, the following code also works:
MyClass my;
int *pn = &my.n;
*pn = 1;

Yeh, pointer to member function is more useful then pointer to member
the existence of *mem_fun* family can somehow defend this.

and we can't take the address of member function from an instance of
some class.

struct A
{
void print(){}
};

int main()
{
void (*pf)();
A a;
&a.print; // illformed
}

so there's no way to do the same thing as you did in your example.

IMHO, pointer to member function / pointer to member has goodness for
late binding, that's to say, such pointers can pointer any member/member
function of the same type after it's declared.

here's an example when we need (or it's good to use) pointer to member:

#include <vector>
#include <algorithm>
#include <iostream>

struct A
{
A (char x, int y, int z)
: x(x), y(y), z(z) {}
char x;
int y;
int z;
};

typedef int A::*pmA;

struct Selector
{
Selector(pmA pm) : pm_(pm) {}
int operator() (A const& a) const
{
return a.*pm_;
}
private:
pmA pm_;
};

template <class T>
struct Printer
{
void operator() (int i) const
{
std::cout << i << ' ';
}
};

int main()
{
std::vector<A> aVec;
std::vector<int> intVec;
for (int i = 0; i < 10; ++i)
aVec.push_back(A((char)i, i, i+1));

std::transform(
aVec.begin(), aVec.end(),
std::back_inserter(intVec),
Selector(&A::y) // 0 1 2 3 4 5 6 7 8 9
// Selector(&A::z) // 1 2 3 4 5 6 7 8 9 10
);

Printer<int> printer;
std::for_each(intVec.begin(), intVec.end(), printer);
}
 
G

Guest

Hello. I am rather confused by the type of a pointer to class data
member. Many c++ texts say that pointer to data member has a special
syntax. For example the following class:
class MyClass
{
public:
int n;
};

The pointer to MyClass.n shall be defined like this:
typedef int MyClass::*pn_t;
pn_t pn = &MyClass::n
MyClass my;
my.*pn = 1;

But at the same time, the following code also works:
MyClass my;
int *pn = &my.n;
*pn = 1;

So I wonder if the second method is legal in the c++ standard. If it
is, why bother to have the first method?

I think that both forms are legal, however notice that the first is more
powerful than the second since it does not require an object of type
MyClass.
 
B

Barry

Barry said:
Yeh, pointer to member function is more useful then pointer to member
the existence of *mem_fun* family can somehow defend this.

and we can't take the address of member function from an instance of
some class.

struct A
{
void print(){}
};

int main()
{
void (*pf)();
A a;
&a.print; // illformed
}

so there's no way to do the same thing as you did in your example.

IMHO, pointer to member function / pointer to member has goodness for
late binding, that's to say, such pointers can pointer any member/member
function of the same type after it's declared.

here's an example when we need (or it's good to use) pointer to member:

#include <vector>
#include <algorithm>
#include <iostream>

struct A
{
A (char x, int y, int z)
: x(x), y(y), z(z) {}
char x;
int y;
int z;
};

typedef int A::*pmA;

struct Selector
{
Selector(pmA pm) : pm_(pm) {}
int operator() (A const& a) const
{
return a.*pm_;
}
private:
pmA pm_;
};

And I can make it more generic and offer a "mem_fun"-like helper

template <class Klass, class Type>
struct Selector
{
Selector(Type Klass::* pm) : pm_(pm) {}
int operator() (A const& a) const
{
return a.*pm_;
}
private:
Type Klass::* pm_;
};

template <class Klass, class Type>
Selector<Klass, Type> Select(Type Klass::* pm)
{
template <class T>
struct Printer
{
void operator() (int i) const
{
std::cout << i << ' ';
}
};

int main()
{
std::vector<A> aVec;
std::vector<int> intVec;
for (int i = 0; i < 10; ++i)
aVec.push_back(A((char)i, i, i+1));

std::transform(
aVec.begin(), aVec.end(),
std::back_inserter(intVec),
Selector(&A::y) // 0 1 2 3 4 5 6 7 8 9
// Selector(&A::z) // 1 2 3 4 5 6 7 8 9 10
Select(&A::x)
//Select(&A::y)
//Select(&A::z)
 
P

Pete Becker

Hello. I am rather confused by the type of a pointer to class data
member. Many c++ texts say that pointer to data member has a special
syntax. For example the following class:
class MyClass
{
public:
int n;
};

The pointer to MyClass.n shall be defined like this:
typedef int MyClass::*pn_t;
pn_t pn = &MyClass::n
MyClass my;
my.*pn = 1;

But at the same time, the following code also works:
MyClass my;
int *pn = &my.n;
*pn = 1;

So I wonder if the second method is legal in the c++ standard. If it
is, why bother to have the first method?

The first is a pointer to member of class MyClass of type int, the
second is a pointer to int. They do two different things. *pn always
points to my.n. pn_t points to the n member of any object of type
MyClass:

MyClass m1;
MyClass m2;

m1.*pn points to m1.n, and m2.*pn points to m2.n.
 
W

WaterWalk

Yeh, pointer to member function is more useful then pointer to member
the existence of *mem_fun* family can somehow defend this.

and we can't take the address of member function from an instance of
some class.

struct A
{
void print(){}

};

int main()
{
void (*pf)();
A a;
&a.print; // illformed

}

so there's no way to do the same thing as you did in your example.

IMHO, pointer to member function / pointer to member has goodness for
late binding, that's to say, such pointers can pointer any member/member
function of the same type after it's declared.

here's an example when we need (or it's good to use) pointer to member:

#include <vector>
#include <algorithm>
#include <iostream>

struct A
{
A (char x, int y, int z)
: x(x), y(y), z(z) {}
char x;
int y;
int z;

};

typedef int A::*pmA;

struct Selector
{
Selector(pmA pm) : pm_(pm) {}
int operator() (A const& a) const
{
return a.*pm_;
}
private:
pmA pm_;

};

template <class T>
struct Printer
{
void operator() (int i) const
{
std::cout << i << ' ';
}

};

int main()
{
std::vector<A> aVec;
std::vector<int> intVec;
for (int i = 0; i < 10; ++i)
aVec.push_back(A((char)i, i, i+1));

std::transform(
aVec.begin(), aVec.end(),
std::back_inserter(intVec),
Selector(&A::y) // 0 1 2 3 4 5 6 7 8 9
// Selector(&A::z) // 1 2 3 4 5 6 7 8 9 10
);

Printer<int> printer;
std::for_each(intVec.begin(), intVec.end(), printer);

}

This is example is instructive. I at last see some application of
pointer-to-class-data-member. Thanks
 
W

WaterWalk

Thanks for your help. I now have a better understand of pointer-to-
member.

However, since there are actually two ways to access class data
members: one is via plain data object pointer, the other is pointer-to-
data-member, I think this can also be expanded to class functions. At
present, among all kinds of pointers, only pointer-to-class-function-
member can be used to access class member functions. Why not allow
plain function pointer to do this. Like:
typedef void (*pfunc_t) ();
class MyClass
{
public:
void doSomething();
};
MyClass my;
pfunc_t pf = &my.doSomething;

In this case, function pointer is like a closure. I guess probably
it's because the implementation isn't easy. What's more, we can use
functors. So this may not be a problem.
 
V

Victor Bazarov

WaterWalk said:
Thanks for your help. I now have a better understand of pointer-to-
member.

However, since there are actually two ways to access class data
members: one is via plain data object pointer, the other is
pointer-to- data-member, I think this can also be expanded to class
functions. At present, among all kinds of pointers, only
pointer-to-class-function- member can be used to access class member
functions. Why not allow plain function pointer to do this. Like:
typedef void (*pfunc_t) ();
class MyClass
{
public:
void doSomething();
};
MyClass my;
pfunc_t pf = &my.doSomething;

In this case, function pointer is like a closure. I guess probably
it's because the implementation isn't easy. What's more, we can use
functors. So this may not be a problem.

I think you should talk yourself into posting to comp.std.c++. The
syntax "&my.doSomething" to combine the pointer-to-non-static-member
and the instance for which it's called through the pointer to function
to which it's assigned is not that difficult to implement, all one
would need is a proxy (a wrapper) that would essentially be taking
the pointer to the object and the pointer to the member, and putting
them together behind the scenes. Now, whether it's a good idea and
what the pitfalls might be, I am not sure.

Put together a proposal and post to comp.std.c++ to discuss it.

V
 
B

Barry

WaterWalk said:
Thanks for your help. I now have a better understand of pointer-to-
member.

However, since there are actually two ways to access class data
members: one is via plain data object pointer, the other is pointer-to-
data-member, I think this can also be expanded to class functions. At
present, among all kinds of pointers, only pointer-to-class-function-
member can be used to access class member functions. Why not allow
plain function pointer to do this. Like:
typedef void (*pfunc_t) ();
class MyClass
{
public:
void doSomething();
};
MyClass my;
pfunc_t pf = &my.doSomething;

struct HisClass
{
voud doSomething();
};

HisClass he;
(he.pf)(); ??
 
V

Victor Bazarov

Barry said:
struct HisClass
{
voud doSomething();
};

HisClass he;
(he.pf)(); ??

Shouldn't work. 'pf' is not a member of 'HisClass'. However, if
WaterWalk's suggestion would be implemented, then

pf();

would be exactly the same as

my.doSomething();

V
 
B

Barry

Victor said:
Shouldn't work. 'pf' is not a member of 'HisClass'. However, if
WaterWalk's suggestion would be implemented, then

pf();

would be exactly the same as

my.doSomething();

:)

actually, I was trying t persuade to OP from posting proposal to c.l.c++.std
 
V

Victor Bazarov

Barry said:
:)

actually, I was trying t persuade to OP from posting proposal to
c.l.c++.std

I am guessing you meant "dissuade the OP".

First off, it's c.s.c++ (comp.std.c++) and second, why? Most of our
favourite language is syntactic sugar anyway, why not add a bit more
to our life? :)

I actually think that if we had something like that, callbacks would
become so much easier, no? Thread functions too.

V
 
B

Barry

Victor said:
I am guessing you meant "dissuade the OP".

First off, it's c.s.c++ (comp.std.c++) and second, why? Most of our
favourite language is syntactic sugar anyway, why not add a bit more
to our life? :)

I actually think that if we had something like that, callbacks would
become so much easier, no? Thread functions too.

yeh,

Just like I did, adding English syntax sugar "persuade somebody from
doing something" means "talk somebody out of doing something"

:)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top