What exactly is the ->* operator? - c++

I've never used it before and just stumbled upon it in an article... I thought it would be the equivalent to *x->y but apparently it isn't.
Here's what I tried, and gave me an error:
struct cake {
int * yogurt;
} * pie;
int main(void) {
pie = new cake;
pie->yogurt = new int;
return pie->*yogurt = 4;
}

Its used when you have pointers to member functions.
When you have a pointer to a function of a class, you call it in much the same way you would call any member function
object.membername( ... )
or
objectptr->membername( ... )
but when you have a member function pointer, an extra * is needed after the . or -> in order that the compiler understand that what comes next is a variable, not the actual name of the function to call.
Here's an example of how its used.
class Duck
{
public:
void quack() { cout << "quack" << endl; }
void waddle() { cout << "waddle" << endl; }
};
typedef void (Duck::*ActionPointer)();
ActionPointer myaction = &Duck::quack;
void takeDuckAction()
{
Duck myduck;
Duck *myduckptr = &myduck;
(myduck.*myaction)();
(myduckptr->*myaction)();
}

It defines a pointer to a member.
In an expression containing the –>* operator, the first operand must
be of the type "pointer to the class type" of the type specified in
the second operand, or it must be of a type unambiguously derived from
that class.
MSDN

Pointer-to-Member Operators: .* and ->*

The .* and ->* operators will point to member functions of a class or structure. The code below will show a simple example of how to use the .* operator, if you change the line:
Value funcPtr = &Foo::One; to Value funcPtr = &Foo::Two; the result displayed will change to 1000 since that function is inValue*2
for example Taken From Here:
#include <iostream>
#include <stdlib.h>
class Foo {
public:
double One( long inVal ) { return inVal*1; }
double Two( long inVal ) { return inVal*2; }
};
typedef double (Foo::*Value)(long inVal);
int main( int argc, char **argv ) {
Value funcPtr = &Foo::One;
Foo foo;
double result = (foo.*funcPtr)(500);
std::cout << result << std::endl;
system("pause");
return 0;
}

Related

C++ - calling a member function of another class using a pointer

I'm testing, trying to call a member function being passed as a parameter,
the member function has to be one of another class.
this is an example, which gives an error:
"pointer-to-member selection class types are incompatible ("B" and
"A")"
This is the code, what am I doing wrong?
#include <iostream>
using namespace std;
class A {
private:
public:
void fA(int x) {
cout << "hello" << endl;
}
void fB(int x) {
cout << "good bye" << endl;
}
A() {
}
};
class B {
private:
void (A:: * f)(int) = NULL;
public:
B(void (A:: * f)(int)) {
this->f = f;
}
void call() {
(this->*f)(10); //What's wrong here?
}
};
A a = A();
B b = B(&(a.fA));
B b2 = B(&(a.fB));
int main(void) {
b.call();
b2.call();
}
&(a.fA) is not legal C++ syntax. &A::fA is. As you can see, there is no object of type A anywhere of this syntax. &A::fA is just a pointer to a member function, not a pointer-to-member-together-with-an-object combo.
Now in order to call that pointer-to-member, you need an object of class A. In class B, you don't have any. You need to get one in there somehow, and call the function this way:
(a->*f)(10);
where a is a pointer to that object of class A.

C++: How to iterate over a list of class types for typeid verification and downcasting?

I would like to perform a down casting at execution time.
For what I read, if I want to do it, I need to compare the typeid of my polymorphic pointer with those of my derived classes, then do the casting in the correct type.
Plus, let's assume that I have a large number of derived classes.
This implies I have to write a long switch or list of if.
I would like to reduce this effort by using a list of classes to check.
This could look like:
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
using namespace std;
class BaseShapes
{
virtual int run() = 0;
};
class ClassRectangle : public BaseShapes
{
int run()
{
std::cout << "I am a Rectangle. " << std::endl;
return 0;
}
float get_length () {return 12.4;};
float get_width() {return 6.2;};
};
class ClassCircle : public BaseShapes
{
int run()
{
std::cout << "I am a Cricle. " << std::endl;
return 0;
}
float get_diameter() {return 5.3;};
};
float function_only_for_Rectangle(ClassRectangle *rectangle)
{
// a function coming from a library that I cannot touch and that requires a derived type.
// But for the example I do something dummy!
return rectangle->get_length()
};
auto downcast_function (auto *p)
{
enum ListOfTypes {
ClassCircle,
ClassRectangle,
// and a lot more differents classes
};
for ( int fooInt = ClassCircle; fooInt < ClassRectangle; fooInt++ )
{
ListOfTypes fooItem = static_cast<ListOfTypes>(fooInt);
if (typeid(p) == typeid(fooItem))
{
auto pCasted =dynamic_cast<fooItem>(p);
return pCasted;
}
}
std::cout<< "downcast_function warning: no typeid is matching !" << std::endl;
return p;
};
int main(void)
{
// Beginning of main.
cout << "(Start)" << endl;
std::unique_ptr<BaseShapes> Shape1(new ClassRectangle());
auto p=Shape1.get();
//function_only_for_Rectangle(p); // not working since p is of type BaseShapes*
auto pbis=downcast_function(p); // should be of type ClassRectangle*
function_only_for_Rectangle(pbis);
// End of the main.
cout << "(End) " << endl;
return 0;
}
// EoF
So how can I write the downcast_function ? Or in other words, how can I iterate over a list of class types in order to make a typeid comparison and a casting ?
More details:
I agree that in this dummy example, I could simply override a function for each derived class and that is a much better way to deal with polymorphism. But I need to downcast, this is a constrain coming from a more complex problem where they are things that I am not allowed to changed. So, the question here is not why downcast but how.
To give a bit more details about my constrains are:
To start from a base pointer.
Get a derived pointer and give it to an external function (here called function_only_for_Rectangle, so I cannot modify this function).
I cannot do a simple and direct dynamic_cast<ClassRectangle>(p) because the type of p (or equivalently Shape1) will change at running time. This means that Shape1 can have "randomly" any derived type from BaseShapes. So I need something "automatic" and this is why I was thinking about iterate over all derived types and downcast according to the typeid match (but I am open to better ideas).
All the classes can modified if needed.
You say "polymorphic" but what you want to do is the opposite of it.
Instead of trying to work against polymorphism you could actually use it. If all subclasses have their own implementation of a virtual function then the caller does not need to care what the actual dynamic type of the object is. That is runtime polymorphism in a nutshell.
I suppose the naming for run is only for the example. Give it a better name, supply a default implementation in the base class, implement specific behavior in ClassRectangle and let the caller call it. No need to cast.
class BaseShapes
{
virtual int do_something_rectangly() { return 0;}
~virtual BaseShapes() = default;
};
class ClassRectangle : public BaseShapes
{
int do_something_rectangly() override
{
std::cout << "I am a Rectangle. " << std::endl;
return 0;
}
};
class ClassCircle : public BaseShapes
{
// does not override do_something_rectangly()
};
int function_for_any_base_shape(BaseShapes& s)
{
return s.do_something_rectangly();
};
int main(void)
{
// Beginning of main.
cout << "(Start)" << endl;
std::unique_ptr<BaseShapes> Rec1(new ClassRectangle());
function_for_any_base_shape(*pbis);
cout << "(End) " << endl;
return 0;
}
Concerning your edit:
I cannot do a simple and direct dynamic_cast(p) because the type of p (or equivalently Shape1) will change at running time. This means that Shape1 can have "randomly" any derived type from BaseShapes. [...]
Either I misunderstand what you wrote completely or you misunderstand how dynamic_cast works. dynamic_cast does already check what the dynamic type of the object is:
BaseShapes* b1 = new ClassCircle;
if(ClassRectangle* d = dynamic_cast<ClassRectangle*>(b1))
{
// cast is sucessfull
function_only_for_Rectangle(d);
} else {
// dynamic type of b1 is not ClassRectangle
}
To call function_only_for_Rectangle you do not need to be able to cast to all subtypes of ClassBase. You only need to dynamic_cast to a pointer to ClassRectangle and check if the cast was sucesfull.

How to use two constructors?

I have a code like this.
#include <iostream>
#include <vector>
using namespace std;
class AbstractValueC{
private:
long age = 0;
int abs;
bool spec = false;
public:
AbstractValueC() {
abs = 0;
}
AbstractValueC(int& a, bool b = false){
abs = *a;
spec = b;
}
AbstractValueC(int a, bool b = false){
abs = a;
spec = b;
}
int get_value() const {
return abs;
}
long get_age(){
return age;
}
};
int main(){
vector<AbstractValueC> v;
int init = 1;
int next = 2;
v.push_back(AbstractValueC(std::move(init)));
cout << "I have created first v element." << endl;
v.push_back(AbstractValueC(std::move(next)));
cout << "I have created second v element." << endl;
std::vector<AbstractValueC> result;
for (auto a : v) {
int pre = a.get_value();
result.push_back(AbstractValueC(pre));
}
cout << "I have created result." << endl;
return 0;
}
Please tell me how to solve the error of
invalid type argument of unary ‘*’ (have ‘int’)
abs = *a;
^
and the error
call of overloaded ‘AbstractValueC(int&)’ is ambiguous
result.push_back(AbstractValueC(pre));
^
I actually have a custom type (Abs) in place of int for the abs member in my actual code. Also the requirement is that I cannot call the default constructor of Abs in main. I can use abs = Abs::null;. So please suggest a solution that avoid calling the default constructor for Abs if I replace int with Abs in the class definition.
invalid type argument of unary ‘*’ (have ‘int’)
AbstractValueC(int& a, bool b = false){
abs = *a;
spec = b;
}
Argument a is an int reference, not a pointer, so you can't dereference as *a.
The code should be abs = a;
call of overloaded ‘AbstractValueC(int&)’ is ambiguous
As #strom points out in the comments, you have 2 similar constructors:
AbstractValueC(int& a, bool b = false)
AbstractValueC(int a, bool b = false)
Which the compiler cannot readily distinguish between. You should get rid of one of them.
The real problem is that you are using two constructors with the same signature :
How does the compiler choose between using :
AbstractValueC v=AbstractValueC(value);//int constructor
And
AbstractValueC v=AbstractValueC(value);//reference constructor
When you have
Int value = 0;//for example
To get rid of this error(ambigueous constructor call) you could either change one of the constructors or replace your reference constructor with a pointer constructor
To change the constructor to a pointer, you need to create a value pointer in your class and create a contructor:
// in class declaration
Int *pointerValue = nullptr;
AbstractValueC(int* pointer, bool b = false);
// implementation
AbstractValueC::AbstractValueC(Int *pointer, bool b=false) {
pointerValue=pointer;
}

const-correctness for this and member functions

assuming that I have a generic class A
class A {
...
int a; // a member
void foo() const{...} // a member function qualified as const
...
};
this implies that if I declare an instance of A like A k; and then I call k.foo(); the this pointer that is acting on/inside that call to foo is something of type const A * const .
Now I would like to know why the code in this blog post works, especially about why this doesn't apply to global variables.
My explanation is about an hidden operation about pointer aliasing, like the this pointer being copied implicitly and during this copy the result is not const anymore ( for some reason ... ) but it's still a this pointer meaning that is a pointer to the same instance.
My question is about: what really const does if it's applied after the declaration of an interface for a member function ? Do you have a specific answer for the linked blog post ?
code from the blog
#include <iostream>
class counter {
public:
int i;
counter();
int inspect() const;
void increment();
};
counter sigma_inspect; // sigma_inspect is global
counter::counter() { i = 0; }
int counter::inspect() const {
sigma_inspect.increment();
return i;
}
void counter::increment() {
++i;
return;
}
int main(void) {
counter a;
std::cout << a.inspect() << "\n";
std::cout << sigma_inspect.inspect() << "\n";
std::cout << sigma_inspect.inspect() << "\n";
return 0;
}
The call in the blog post is using sigma_inspect which is non-const and it is calling a non-const method on it instead of calling said method through the const this pointer. So what? The author seems to expect magic instead of the obvious of what he wrote. It's like having
T* t = ...;
const T* ct = t;
t->foo(); // foo() is not const, but hey,
// I also have a const pointer now (ct),
// so why can I still use this???
Generally, if someone calls C++ stupid it tells you more about the author instead of the language :)

c++ pointers to operators

I want to write a pointer in c++ (or in c++0x), that will points to a operator of a class lets say A or B.
Is there any method to do it?
Of course there is a syntax like
int (A::*_p) ();
but it doesn't solve this problem. I want to make general pointer, not specifying the base class for it - only pointer for "operator function"
#include <thread>
#include <iostream>
using namespace std;
class A
{
public:
int operator()()
{
return 10;
}
};
class B
{
public:
int operator()()
{
return 11;
}
};
int main()
{
A a;
int (*_p) ();
_p = a.operator();
cout << _p();
B b;
_p = b.operator();
cout << _p();
}
No, you can't do this. The class type is a part of the type of the operator member function.
The type of A::operator()() is different from the type of B::operator()(). The former is of type int (A::*)() while the latter is of type int (B::*)(). Those types are entirely unrelated.
The closest you can get is by using something like the C++0x polymorphic function wrapper function (found in C++0x, C++ TR1, and Boost) and by using bind to bind the member function pointer to a class instance:
std::function<int()> _p;
A a;
_p = std::bind(&A::operator(), a);
std::cout << _p();
B b;
_p = std::bind(&B::operator(), b);
std::cout << _p();