C++ object reference - c++

I have this piece of code:
Wmmbid02 wmmbid02;
wmmbid02.Omplir(this);
return wmmbid02;
and Wmmbid02.h:
class Wmmbid02: public Idoc {
public:
Wmmbid02();
//void EscriureFitxer();
void Omplir(Edi);
private:
Segment crearSegment(string a[], string b[]);
Info crearInfo(string);
//virtual void LlegirFormat(string);
};
Visual Studio, returns and error because can't convert 'Edi *const ' to 'Edi'.
What is the correct answer???
Thanks

Your declaration of Omplir
void Omplir(Edi);
says that this method take an Edi object.
In C++ this is a pointer. You should use it inside a class.
If you want it to work, you should dereference it:
wmmbid02.Omplir(*this);
The standard says about the this pointer:
9.3.2 The this pointer [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*, [...]
So in your case, you seem to be in a member function of the class Edi, this should be of the type Edi*.

Without seeing the definition for this I'd say you'll probably want to replace void Omplir(Edi); by void Omplir(Edi* const); and adapt the definition of Omplir accordingly.

Either define the parameter void Omplir(Edi) to a pointer:
void Omplir(Edi*);
Or pass this as reference:
Wmmbid02 wmmbid02;
wmmbid02.Omplir( *this );
return wmmbid02;
But it really depends on what you exactly want to do. Usually i prefer passing by references whenever possible.

Related

pass a function pointer between classes

I have two claces.
here is the first one
class one{
one(){ }
public:
void change(double a){
//print a
}
void run(){
two tw;
tw->functionpointer=&change;
}
};
and here is the two class
public two{
two();
static void progresschange(double v){
functionpointer(v);
}
public:
void (*functionpointer)(double);
};
as you see in example I have a function in class one, I want to call it from an static function in class two As progresschange is static I can only call change function in class one uisng function pointers. but It does not work and compiles says
error: cannot convert ‘void (one::*)(double)’ to ‘void (*)(double)’ in assignment
it happens in this line
tw->functionpointer=&change;
how can I make it work. it is even possible to pass a function using its function pointer to another class using this method?
thanks
The error message is quite straightforward:
error: cannot convert void (one::*)(double) to void (*)(double) in assignment
void one::change(double) is a member function of the class one, not just a function. Therefore, you can't assign a pointer to this member function (i.e.: void (one::*)(double)) to a pointer to a function with the same signature (i.e.: to a void (*)(double)).
Besides, a non-static member function (like one::change() above) has to be called on an object, so you also need to provide an one object to call that pointed-to non-static member function.
Basically, you can achieve what you want by adding the following data members in two:
void (one::*mem_func_ptr)(double);
one *obj_ptr;
That is, a pointer to the member function (mem_func_ptr) and a pointer to the object to call this member function on (obj_ptr).
To assign to the member function pointer:
mem_func_ptr = &one::change;
Then, to call the member function pointed by mem_func_ptr on the object pointed by obj_ptr with 0.0 as argument:
(obj_ptr->*mem_func_ptr)(0.0);
It can be done analogously by keeping a copy of an object one as data member instead of a ponter. In that case you should use the operator .* instead of ->*.
The problem is that one::change() is a class member so you need to pass a pointer to a class instance as well.
The modern way to do it is to use std::function, std::bind and std::mem_fn:
class two {
....
std::function<void(double)> functionpointer;
}
tw->functionpointer = std::bind(std::mem_fn(&one::change), _1, one_instance);
Alternatively you can use a lambda function:
tw->functionpointer = [&one_instance](double x) { one_instance->change(x); }

const member function can modify data member

The question: Why can a const member function sometimes modify a data member and sometimes not?
The explanation: The code below is an excerpt from working code in my baseline at work.
I have a Calculator class that owns a data member called "theLayout" (Header and Implementation defined below). The calculator class has a const member function called "Parms()" which returns a smart pointer to a Parms object that theLayout owns (by calling its own Parms() function).
The calculator class has a const member function called calculateStart() which sets (i.e. modifies) the reference returned from calling the Parms() function in the Calculator class.
This seems to contradict the meaning of const to me. If the const member function cannot modify the this pointer, then why can it set a value on one of the data members (theLayout) that it owns? Doesn't this "modify" the this pointer of the Calculator instance, and thus contradict the meaning of a const member function? Does this work because theLayout is a pointer?
Calculator Class
//Header
class Calculator
{
public:
Calculator();
//ParmsPtr is refcounted smart pointer
const ParmsPtr& parms() const {return theLayout->parms();}
protected:
void calculateStart() const; //Why does this work?
//It seems more intuitive that this should be declared as:
void calculateStart() //with no const modifier.
Layout& theLayout;
}
//Implementation
void Calculator::calculateStart() const
{
parms()->setStart(1);
}
Layout Class
//Header
class Layout : public RefCountedObject
{
public:
Layout();
//ParmsPtr is refcounted smart pointer
inline const ParmsPtr& parms() const;
private:
ParmsPtr theParms;
}
//Implementation
inline const ParmsPtr& Layout::parms() const
{
if (!theParms)
{
Layout* nonConstThis = const_cast<Layout*>(this);
ParmsPtr parms = new Parms();
nonConstThis->setParms(parms);
}
return theParms;
}
The calculator class has a const member function called calculateStart() which sets (i.e. modifies) the reference returned from calling the Parms() function in the Calculator class.
Yes, calculateStart() does modify the Calculator object, which is unexpected considering the final const qualifier in its definition.
Why ? Look at definition of inline const ParmsPtr& Layout::parms() const; the final const tells the compiler that the function will not modify the Layout object, though it actually does. How ? By mischeviously const_cast'ing the object to a non-const object; that's where the constness is broken and that's why setParms() can be called.
This is a bad practice, though there may be some reasons to do it. In such cases, const_cast serves this purpose.
The critical question is, what exactly is being made const by declaring start() to be const? The answer is the reference, not the value referenced.
In your example, inside the start() method, the compiler sees the data member as having type Layout const&, which is not the same as const Layout&. The same thing applies to pointers. If your data member was a pointer type, the compiler would see the type as Layout const*.

C++ pointer to a function

In my code I would like to call different functions by the same name. So I used pointers, and I did work with static functions, now I would like to do the same with non-static functions and it doesn't work at all.
class Amrorder
: {
public:
....
void (*fkt)(real&, const real);
void fktAcPulse(real &rhoRef, const real y);
void fktAcPulseSol(real &rhoRef, const real y);
...
}
void Amrorder::initData(a)
{
...
switch(method){
case 2://
Amrorder::fkt=&Amrorder::fktAcPulse;
break;
case 222://
Amrorder::fkt=&Amrorder::fktAcPulse1d;
break;
}
...
for(int i=0; i<ng; ++i){
Amrorder::fkt(rhoRef, yRef);
...
}
...
}
The code is quiet big so I hope the part above is enough to understand what I want to do.
Thanks for your time!
It doesn't work because your fkt has type:
void (*)(real&, const real);
and you're trying to assign it to, e.g., &Amrorder::fktAcPulse, which has type:
void (Amrorder::*)(real&, const real);
Notice the difference. The latter is a pointer-to-member function, not just a pointer to function. These have different semantics. A pointer to function can just be called (e.g. fkt(a, b)), but a pointer to member function needs to be called on an object (e.g. (obj.*pm)(a, b)).
For simplicity, since you probably just want "something that I can call with a real& and a const real", you may want to consider the type-erased function object: std::function:
std::function<void(real&, const real)> fkt;
This can be initialized with any callable that matches the arguments, so you can assign it to a free function:
void foo(real&, const real) { ... }
fkt = foo;
A static member function:
struct S { static void bar(real&, const real) { ... } };
fkt = &S::bar;
Or a member function, as long as its bound:
fkt = std::bind(&Amrorder::fktAcPulse, this);
fkt = [this](real& a, const real b){ return this->fktAcPulse(a, b); };
The key is that you need an instance of Amrorder to call fktAcPulse, and using std::function lets you use either std::bind or a lambda to store that instance in with the functor itself.
The type of fkt declares a function pointer to a free-standing function or a static member function. But you want to assign a non-static member function pointer to it. So fkt needs to be of the type of a non-static member function pointer of class Amrorder. That type is spelled
void (Amrorder::*fkt)(real&, const real);
// ^^^^^^^^^^
When invoking a function pointer to a non-static member function, you need to specify on which object you want the member to be called (which normally defaults to this when calling a member function directly with its name).
The syntax for this is quite strange. It requires another pair of parentheses and depends on wether you call it on a pointer or an object itself:
(object.*functionPointer)(arguments);
(pointer->*functionPointer)(arguments);
So if you just want to call the function on the this pointer, you need to write
(this->*fkt)(rhoRef, yRef);
(Note that you don't need to specify the class in your code everywhere. Amrorder:: can be removed in front of every function name inside the definition of a member function of the same class.)
When you call a non-static method of a class, the compiler needs to know which instance of the class you want to execute against. So there is a hidden parameter in the call, which is a pointer to the instance.
So you need to write something like this:
Amrorder::fkt=bind( &Amrorder::fktAcPulse, this );

Declaring C++ member function as static const yields errors

I have the following class interface:
class Test
{
public:
Test();
static void fun() const;
private:
int x;
static int i;
};
Test.cpp contains fun()'s implementation:
void Test::fun() const
{
cout<<"hello";
}
it is giving me errors... modifiers not allowed on static member functions
What does the error mean? I want to know the reason why I am not able to create a function which is static as well as const.
void fun() const;
means that fun can be applied to const objects (as well as non const).
Without the const modifier, it can only be applied on non const object.
Static functions by definition need no object.
A member function being const means that the other non-const members of the class instance can't be called.
A free function isn't a member function, so it's not associated as to a class or class instance, so it can't be const as there is no member.
A static function is a free function that have it's name scoped inside a class name, making it always relative to a type, but not associated to an instance of that type, so there is still no member to get access to.
In those two last cases, there is no point in having const access, as there is no member to access to.
Static functions work without an instance, whereas const guarantees that the function will not change the instance (even though it requires an instance).
It may be easier to understand if you see the translated code:
static void fun();
at the end of the day is translated to a function that takes no argument, namely
void fun();
For the other example,
void fun() const;
at the end of the day is translated to a function of the form
fun(const Test& self)
Thus, static void fun() const has two contradictory meanings.
BTW: This translation occurs for all member functions (const or not)
i answered this a few hours ago here: Why we need to put const at end of function header but static at first?
(SO system is not happy with my response. automatically converted to comment)
Perhaps it would help to have a simple code example.
class Foo {
public:
static void static_function();
void const_function() const;
};
// Use of static function:
Foo::static_function();
// Use of const function:
Foo f;
f.const_function();
The key difference between the two is that the const function is a member function -- that is, it is invoked on instances of the Foo class. That means you first need to instantiate an object of type Foo, and then that object acts as the receiver of the call to const_function. The const itself means that you won't modify the state of the object which is the receiver of that function call.
On the other hand, a static function is essentially a free function, where you can call it without a receiving object. Outside the scope of the class where it's defined, however, you'll need to qualify it using the class name: Foo::static_function.
This is why it doesn't make sense to have a function which is both static and const, as they're used in entirely different contexts. There's no need to worry about modifying the state of any object when invoking a static function because there is no receiving object -- it is simply invoked like a free function.
Because a static const function of a class does not make sense. const means that a thing (object/variable) stays the same. Static means that a thing object etc stays the same in that context.

How do I call a member function pointer using a pointer to a constant object?

Here is an example of what I want to accomplish and how:
class MyClass
{
public:
void Dummy() const{}
};
typedef void (MyClass::*MemFunc)();
void (const MyClass * instance)
{
MemFunc func=&MyClass::Dummy;
// (instance->*func)(); //gives an error
(const_cast<MyClass *>instance->*func)(); // works
}
Why do compilers (gcc 3 & 4) insist that instance should be non-const? Would that const_cast cause issues?
FYI: instance` is not necessarily const, I just don't want a callee to mess with it.
What is happening here?
The error is in the line before. Change the typedef to
typedef void (MyClass::*MemFunc)() const;
To make it a pointer to a const member function type.
The difference might be more clear when considering this code and how it works:
typedef void FunctionType() const;
typedef FunctionType MyClass::*MemFunc;
A member-function pointer in particular is actually just a special case of a member-pointer in general. For a const member function, the function type of the member function is different than for a non-const member function. That is why the types have to match.
typedef void (MyClass::*MemFunc)();
Here you are defining a pointer to a function which might modify its object.
MemFunc func=&MyClass::Dummy;
Here you are assigning a function which won't change it's object to such a pointer. This is legal, since not changing is a subset of might change.
(instance->*func)();
Here you are trying to call a function which might change its object, using an object which cannot be changed.
You will need to change the definition of MemFunc