What are pointers to class members used for? - c++

I have read about pointers to class members, but I have never seen them being used in any practical applications. Can someone explain what are the use cases of such pointers? Is it really necessary to have such pointers?
Eg.
class abc
{
public:
int a;
abc(int val) { a = val; }
};
int main()
{
int abc::*data;
abc obj(5);
data = &abc::a;
cout << "Value of a is " << obj.*data << endl;
return 0;
}
In the above eg. why is the value of 'a' accessed in this manner? What is the advantage of using pointers to class members?

The biggest advantage of a pointer-to-member or pointer-to-member-function is that you
don't have to bind to a specific instance right away
don't need to place any restrictions on the member names, only the type has to match.
This can be used for e.g. call-backs or abstract algorithms:
std::map<int,int> m;
m.insert(std::make_pair(1,2));
m.insert(std::make_pair(3,4));
m.insert(std::make_pair(5,6));
std::ptrdiff_t s =
std::count_if(m.begin(), m.end(),
boost::bind(&std::map<int,int>::value_type::first, _1) > 2);
std::cout << s << std::endl; // 2
Note that Boost.Bind, Boost.Function and their TR1 equivalents already encapsulate that nicely for you. To a certain degree the current standard also includes tools like std::mem_fun in <functional>.

If you have used MFC, you will see pointers to member function concept is heavily used (internally)
DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP, END_MESSAGE_MAP
See Message Maps

The question I suppose is: "what does pointer to member data add over simple pointer to data?" and the only answer I can think of is a level of explicit meaning: we are pointing at data in this class.
Now I can see some value in what is effectively some additional documentation of intent. One example I've seen that might be quite powerful is when our "class" is actually a legacy C struct. Now we have no local methods of that struct, so having some pointers that are explicitly associated with that struct may well make our code clearer.

Pointer-to-member is, like all C++ features, just syntactic sugar for something you could already have done in pure C.
Pointers-to-member-variable are pretty simple. One use case is if you wanted to write a (template) function that could sort an array of structures by any field. By passing in a pointer-to-member, you can retrieve some specified field of any instance of the structure without having to hard-code the field. Of course a functor that accepts a structure pointer and returns the field value could have been used instead.
Pointers-to-member-function are a little more complicated. At first glance, they are just like ordinary function pointers that know how to pass the hidden 'this' pointer. But virtual functions make a simple idea pretty complicated.
And virtual base classes make all pointers-to-member awfully complicated. It's not something you'd want to code yourself using simple C constructs. But the complex cases are rare.

Related

C++ Why Traits are not available on objects but rather are available as static member variables

My understanding about class Traits is that it is a class that encapsulates a set of types and functions necessary for template classes and template functions to manipulate objects of types for which they are instantiated.
In below example why we cannot make use of 'gquiz::container_type' declaration else how would we know the traits of gquiz :
int main()
{
queue <int> gquiz;
const queue <int>::container_type dq;
//why not gquiz::container_type ?????
cout << typeid(dq).name() << endl;
gquiz.push(10);
gquiz.push(queue <int>::value_type(20));
gquiz.push(30);
}
You can use
decltype(gquiz)::container_type
Indeed having x::y to be meant equivalent as decltype(x)::y when x is not a type would seem simpler and is something that I also (and I bet a lot others) thought about too. However it's not in the standard and the reason is that ... because it's not in the standard, so doesn't work.
Not every decision in C++ has logical grounds, may be this specific one has a logical reason but I cannot think to one.
May be there's just no reason.
With C++ happens. A lot.

Recycling member functionality without inheritance

There is an interesting template presented on Wikipedia for Properties.
This template provides something interesting, in that it allows providing logic around member accesses. Building on this, we could easily build something like this:
struct Ranged {
ranged_property<float,0,1> unit_property;
};
Where the range of unit_property is enforced to be within [0,1].
How can we provide a similar functionality the depends on the hosting class' members? For example:
struct AdjustableRanged {
float max;
ranged_property<float,0,max> influenceable_property;
};
Where the range of influenceable_property is affected by the value of max. Keep in mind, the goal is for this kind of template to be recycled across many vastly different classes. Related concepts are mixins and decorators.
It can be done with macros... but I feel like there must be a better more idiomatic C++ solution.
Edited to add: I think this could be done by saving a reference to the member inside the ranged_property template... but that seems to be a complete waste of space for what would be effectively a constant value; ETA; A const reference may serve the purpose actually, however, I need to do the investigation.
Following up on our discussion in the comments, it seems the functionality can be achieved with a pointer-to-member template parameter like this (but see the caveats below):
#include <iostream>
template<typename C, typename T, T C::*m>
struct PrintMember {
C& obj;
PrintMember(C& obj) : obj(obj) {};
void print() { std::cout << "Member of containing class: " << obj.*m << std::endl; };
};
struct TestClass {
int data;
PrintMember<TestClass, int, &TestClass::data> pm;
TestClass() : pm(*this){};
};
int main()
{
TestClass tc;
tc.data = 5;
tc.pm.print();
}
This only demonstrates that it is possible to access members of the containing object. There are a few things that this approach doesn't solve:
If you really only want to access one member, it's not worth it, since you have to save a reference to *this in the PrintMember member to be able to dereference the pointer to member. So it doesn't actually solve the problem of having to store a reference. You could just as well pass a reference to the member variable itself in the constructor. However, if you need to access multiple members, this allows you to only store one reference (to *this) and still access all of them.
Specifying the template arguments of PrintMember and initializing the PrintMember member variable with *this in the constructor is tedious. Maybe, some clever template argument deduction can help here, but I haven't tried yet and I am not even sure it would get any simpler...
In some special cases, there might be dirty ways to get access to the "this" pointer of the enclosing class without saving it explicitly, like the answer using offsetof in this answer, but my feeling tells me you wanted something portable and less brittle...

Polymorphism - Unsure about derrived class using templates - derrived function returns template type

Recently I've decided to work on a project where I need to have a single object, which can be any data type (uint8, unint16, uint32, or unint64) (I may like to add these are only numbers, and will only be +, -, *, /, <<, >>. I looked into Boost::variant, however after trying it out, I have been discouraged by it as I couldn't retrieve the data correctly. argh - applying visitors?? So I have looked at other methods to emulate this.
Below this point is experimentation, and seems wrong, very wrong:
(I'd like to say that I'm not too in-depth with polymorphism / inheritance, so sorry in advance)
I tried to create a base object, and then set the base object to a derived class - a derived template class which is the data type of my choice(uint8, uint16, uint32, or uint64) After, I can simply retrieve the data which I previously set using the method get():
DynamicVariable *a = new TypedDynamicVariable<unsigned int>(12345);
std::cout << a->get() << std::endl;
delete a;
or:
DynamicVariable *a = new TypedDynamicVariable<unsigned char>(255);
std::cout << a->get() << std::endl;
delete a;
representation example:
unsigned int a = 100;
unsigned char b = 20;
std::cout << a + b << std::endl;
results in: error C2039: 'get' : is not a member of 'DynamicVariable'
I'm getting errors that a->get() doesn't exist in the BASE class. I searched online to find this code (dynamic_cast):
DynamicVariable *a = new TypedDynamicVariable<int>(12345);
TypedDynamicVariable<int>* p = dynamic_cast<TypedDynamicVariable<int>*>(a);
std::cout << p->get() << std::endl;
As you can see, this: TypedDynamicVariable*< int >* and dynamic_cast*>(a) (specifying that it's an INT) to me defeats the whole purpose of what I would like to be doing.
Below is the class that I have sort-of hacked together from many unsure hours of reading online. It seems to have the general outline of my ''solution'' however I DO know that there is important contents missing / needs improving apon, or in fact that polymorphism isn't what I want after all / cannot be used.
class DynamicVariable
{
public:
//constructor & virtual destructor
DynamicVariable() {}
virtual ~DynamicVariable() {}
};
//unique data
template<typename T>
class TypedDynamicVariable : public DynamicVariable
{
private:
T _data;
public:
//constuctor
TypedDynamicVariable (const T& data) : _data(data) { }
//prototypes
void set (const T& data) { _data = data; }
T get (void) { return _data; }
};
If anyone could please help me understand whats wrong with the above class and guide me to a working solution, or point me in the right direction with boost::variant if they are truly what I was looking for after all.
Thanks.
This
DynamicVariable *a = <some initialisation>
std::cout << a->get() << std::endl;
delete a;
does not work, because the compiler must know how to call a->get() without knowing what derived type a actually points to. For this reason, only those members that are part of a's declared (static) type are considered and get is not one of them.
This is the same problem that Boost.Variant and Boost.Any also face.
In the end, it boils all down to one simple thing: If you don't know what type of value is currently stored in a boost::variant<>/boost::any/DynamicVariable, then you can't get that value out.
For Boost.Variant, you retrieve the value with boost::get<type>(variant). For Boost.Any, you retrieve the value with boost::any_cast<type>(any). For DynamicVariable you will probably have to make something similar.
you can use boost::variant if particular types are well known at compile time (you have to provide the list to instantiate it). and only that types can be stored in a variant. then you may use visitors to do smth with stored data (see also which() member-function).
alternatively you may use boost::any w/o any limits on contained data types.
writing your own variant is (almost) impossible to implement in terms of traditional OOP: cuz you need to write a get() member w/ different return type (unknown at compile time). (which is impossible in C++).
and your current wrapper (mostly) useless in terms of polymorphism -- you can have a container of pointers to your base class, but unable to realize what stored inside... so you can't get() anything out from this storage w/ knowledge whats stored in it. you have to provide some methods to do this. and they must use RTTI somehow... so in terms of performance it will be far from perfect... better to use boost::variant
To be able to call get() from the mother class DynamicVariable, you need this method to be defined there, as virtual (pure in your case). So the question is: what is the type that a get() method in DynamicVariable would return? Don't try to find a trick with templates, virtual methods cannot be template.
I'm not a big fan of boost::variant or boost::any (even if there are useful!), it's sometimes a too easy way to solve design problems.
As alternative, I would really think about the application that you have in mind (I guess that your example is simplified). Ask yourself the following question: have the different types returned a common meaning?
If yes, then you should consider having inheritence for the returned type as well: the method get() returns a pointer on a mother class, say GeneralReturnType and the daughter implementations return pointers on classes that are derived from GeneralReturnType.
If no, then you should simply not call get() from the DynamicVariable class: the different return type have no common meaning, so the get() method has a different meaning depending on the class TypedDynamicVariable considered. To call the get() method, you should therefore know which derived class you have (maybe polymorphism isn't what you want, indeed...).

Map functions of a class

Before I was trying to map my classes and namespaces, by using static calls I succeded and now I need to map the functions of my classes because they will be used dynamically.
Firstly I was thinking to hardcode in the constructor so I can assign a std:map with the string of the name of function pointing to the function itself.
for example:
class A{
int B(){
return 1;
}
};
int main(){
A *a = new A();
vector<string, int (*)()> vec;
vector["A.B"] = a.B;
}
By that I have mapped the function B on A class, I know that I only mapped the function the instance and thats B is not static to be globally mapped.
But thats what I need, at somepoint someone will give me a string and I must call the right function of an instance of a class.
My question is if I only can do that by hardcoding at the constructor, since this is a instance scope we are talking or if there is somehow a way to do this in the declaration of the function, like here for namespaces and classes:
Somehow register my classes in a list
If I understand you correctly, you want your map to store a pointer that can be used to call a member function on an instance, the value being chosen from the map at run time. I'm going to assume that this is the right thing to do, and that there isn't a simpler way to solve the same problem. Quite often when you end up in strange C++ backwaters it's a sign that you need to look again at the problem you think you have, and see whether this is the only way to solve it.
The problem with using an ordinary function pointer is that a non-static member function is not an ordinary function. Suppose you could point to a member function with an ordinary function pointer, what would happen when you dereferenced that pointer and called the function? The member function needs an object to operate on, and the syntax doesn't provide a way to pass this object in.
You need a pointer to member, which is a slightly obscure feature with relatively tricky syntax. While an ordinary pointer abstracts an object, a pointer to member abstracts a member on a class; the pointer specifies which class member should be called, but not which object to obtain the member from (that will be specified when the pointer is used). We can use it something like this:
class B;
class A
{
B some_function()
{ /* ... */ }
};
B (A::* myval)() = A::some_function;
Here myval is a variable that indicates one of the members of class A, in this case the member some_function (though it could point to any other member of A of the same type). We can pass myval round wherever we want (e.g. storing it in an STL container, as in your example) and then when we want to call the function, we specify the instance it should be called on in order to locate the function:
A some_a;
B newly_created_b = (some_a.*myval)();
This works for a particular case, but it won't solve your general issue, because member pointers contain the class they refer to as part of the definition. That is, the following two variables are of entirely different types:
B (Foo::* first_variable)() = Foo::some_function;
B (Bar::* second_variable)() = Bar::some_function;
Even though both functions can produce a B when called without arguments, the two values operate on different classes and therefore you can't assign a value of one type to a variable of the other type. This of course rules out storing these different types in a single STL container.
If you're committed to storing these in a container, you'll have to go with a functor-based solution like Charles Salvia proposes.
If I understand you correctly, you're going to have a class like:
struct Foo
{
int bar();
};
And the user will input a string like "Foo::bar", and from that string you need to call the member function Foo::bar?
If so, it's rather awkward to code a flexible solution in C++, due to the static type system. You can use an std::map where the key is a string, and the value is a member function pointer, (or std::mem_fun_t object), but this will only work on a single class, and only on member functions with the same signature.
You could do something like:
#include <iostream>
#include <map>
#include <functional>
struct Foo
{
int bar() { std::cout << "Called Foo::bar!" << std::endl; }
};
int main()
{
std::map<std::string, std::mem_fun_t<int, Foo> > m;
m.insert(std::make_pair("Foo::bar", std::mem_fun(&Foo::bar)));
Foo f;
std::map<std::string, std::mem_fun_t<int, Foo> >::iterator it = m.find("Foo::bar");
std::mem_fun_t<int, Foo> mf = it->second;
mf(&f); // calls Foo::bar
}
just found(using google) a topic to the same question I had with an answer.
What is the simplest way to create and call dynamically a class method in C++?
I didn't try it yet but makes sense, I will ask again later if it doesn't work
ty!
Joe
I must call the right function of an instance of a class.
You need to call a specific method on an existing instance, or you need to create an instance of the appropriate type and call the method?
If it's the former, then you need a std::map or similar that lets you look up instances from their names.
If it's the latter, that's basically what serialization frameworks need to do in order to create the correct type of object when de-serializing, the object that knows how to read the next bit of data. You might take a look at how the Boost serialization library handles it:
boost.org/doc/libs/1_40_0/libs/serialization/doc/serialization.html
Are you doing this in some kind of tight loop where you need the efficiency of a good map? If so, then member function pointers (as you linked to above) is a good way to go. (At least it is after you work around the problem #Tim mentioned of keeping member function pointers to different types in the same collection ... let the language abuse begin!)
On the other hand, if this is in code that's user-driven, it might be more legible to just be totally uncool and write:
if( funcName=="A.b" )
{
A a;
a.b();
} else
// etc etc etc
For the higher-performace case, you can supplement the same approach with a parse step and some integer constants (or an enum) and use a switch. Depending on your compiler, you might actually end up with better performance than using member function pointers in a map:
switch( parse(funcName) )
{
case A_b:
{
A a;
a.b();
}
break;
}
(Of course this breaks down if you want to populate your list of possibilities from different places ... for example if each class is going to register itself during startup. But if you have that kind of object infrastructure then you should be using interfaces instead of pointers in the first place!)

Maintain reference to any object type in C++?

I'm trying to teach myself C++, and one of the traditional "new language" exercises I've always used is to implement some data structure, like a binary tree or a linked list. In Java, this was relatively simple: I could define some class Node that maintained an instance variable Object data, so that someone could store any kind of object in every node of the list or tree. (Later I worked on modifying this using generics; that's not what this question is about.)
I can't find a similar, idiomatic C++ way of storing "any type of object." In C I'd use a void pointer; the same thing works for C++, obviously, but then I run into problems when I construct an instance of std::string and try to store it into the list/tree (something about an invalid cast from std::string& to void*). Is there such a way? Does C++ have an equivalent to Java's Object (or Objective-C's NSObject)?
Bonus question: If it doesn't, and I need to keep using void pointers, what's the "right" way to store a std::string into a void*? I stumbled upon static_cast<char*>(str.c_str()), but that seems kind of verbose for what I'm trying to do. Is there a better way?
C++ does not have a base object that all objects inherit from, unlike Java. The usual approach for what you want to do would be to use templates. All the containers in the standard C++ library use this approach.
Unlike Java, C++ does not rely on polymorphism/inheritance to implement generic containers. In Java, all objects inherit from Object, and so any class can be inserted into a container that takes an Object. C++ templates, however, are compile time constructs that instruct the compiler to actually generate a different class for each type you use. So, for example, if you have:
template <typename T>
class MyContainer { ... };
You can then create a MyContainer that takes std::string objects, and another MyContainer that takes ints.
MyContainer<std::string> stringContainer;
stringContainer.insert("Blah");
MyContainer<int> intContainer;
intContainer.insert(3342);
You can take a look at boost::any class. It is type safe, you can put it into standard collections and you don't need to link with any library, the class is implemented in header file.
It allows you to write code like this:
#include <list>
#include <boost/any.hpp>
typedef std::list<boost::any> collection_type;
void foo()
{
collection_type coll;
coll.push_back(boost::any(10));
coll.push_back(boost::any("test"));
coll.push_back(boost::any(1.1));
}
Full documentation is here: http://www.boost.org/doc/libs/1_40_0/doc/html/any.html
What you are looking for are templates. They allow you to make classes and function which allow you to take any datatype whatsoever.
Templates are the static way to do this. They behave like Java and C# generics but are 100% static (compile time). If you d'ont need to store different types of objetcs in the same container, use this (other answers describe this very well).
However, if you need to store different types of objects in the same container, you can do it the dynamic way, by storing pointers on a base class. Of course, you have to define your own objects hierarchy, since there is no such "Object" class in C++ :
#include <list>
class Animal {
public:
virtual ~Animal() {}
};
class Dog : public Animal {
public:
virtual ~Dog() {}
};
class Cat : public Animal {
public:
virtual ~Cat() {}
};
int main() {
std::list<Animal*> l;
l.push_back(new Dog);
l.push_back(new Cat);
for (std::list<Animal*>::iterator i = l.begin(); i!= l.end(); ++i)
delete *i;
l.clear();
return 0;
}
A smart pointer is easier to use. Example with boost::smart_ptr:
std::list< boost::smart_ptr<Animal> > List;
List.push_back(boost::smart_ptr<Animal>(new Dog));
List.push_back(boost::smart_ptr<Animal>(new Cat));
List.clear(); // automatically call delete on each stored pointer
You should be able to cast a void* into a string* using standard C-style casts. Remember that a reference is not treated like a pointer when used, it's treated like a normal object. So if you're passing a value by reference to a function, you still have to de-refrence it to get its address.
However, as others have said, a better way to do this is with templates
static_cast<char*>(str.c_str())
looks odd to me. str.c_str() retrieves the C-like string, but with type const char *, and to convert to char * you'd normally use const_cast<char *>(str.c_str()). Except that that's not good to do, since you'd be meddling with the internals of a string. Are you sure you didn't get a warning on that?
You should be able to use static_cast<void *>(&str). The error message you got suggests to me that you got something else wrong, so if you could post the code we could look at it. (The data type std::string& is a reference to a string, not a pointer to one, so the error message is correct. What I don't know is how you got a reference instead of a pointer.)
And, yes, this is verbose. It's intended to be. Casting is usually considered a bad smell in a C++ program, and Stroustrup wanted casts to be easy to find. As has been discussed in other answers, the right way to build a data structure of arbitrary base type is by using templates, not casts and pointers.