PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > lifetime of const references...
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
lifetime of const references...

Réponse
 
LinkBack Outils de la discussion
Vieux 08/04/2008, 21h59   #1
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut lifetime of const references...

Here is the code which should compile fine; program output and my question
follows:
__________________________________________________ __________________
#include <cstdio>


namespace func_ptr {
namespace sys {
typedef void (callback_type) (void const* const);

class base_pod {
protected:
callback_type* mp_callback;

public:
void execute() const {
mp_callback(this);
}
};

template<typename T, typename T_mfptr, typename T_p1>
class param_1 : public base_pod{
T m_obj;
T_mfptr m_mfptr;
T_p1 m_p1;

public:
param_1(T obj, T_mfptr mfptr, T_p1 p1)
: m_obj(obj), m_mfptr(mfptr), m_p1(p1) {
mp_callback = sys_callback;
std::printf("(%p)-param_1::param_1()\n",
reinterpret_cast<void*>(this));
}

~param_1() throw() {
std::printf("(%p)-param_1::~param_1()\n",
reinterpret_cast<void*>(this));
}

private:
void callback() const {
(m_obj->*(m_mfptr))(m_p1);
}

static void sys_callback(void const* const state) {
static_cast<param_1 const*>(state)->callback();
}
};
}


typedef sys::base_pod const& handle;


template<typename T, typename T_mfptr, typename T_p1>
sys::param_1<T, T_mfptr, T_p1>
create(T _this, T_mfptr mfptr, T_p1 p1) {
return sys::param_1<T, T_mfptr, T_p1>(_this, mfptr, p1);
}
}


struct object {
void func(int i) {
std::printf("(%p)-object::func1(%d)\n",
reinterpret_cast<void*>(this), i);
}
};


struct holder {
func_ptr::handle m_fptr;
holder(func_ptr::handle fptr) : m_fptr(fptr) {}
};




int main() {
object obj;

{
std::puts("Scope 1:\n");
func_ptr::handle h(func_ptr::create(&obj, &object::func, 123));
h.execute();
}

std::puts("\n\n--------------------------------------------");

{
std::puts("Scope 2:\n");
holder h(func_ptr::create(&obj, &object::func, 123));
h.m_fptr.execute();
}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~*/
std::puts("\n\n--------------------------------------------\n\
Press <ENTER> to exit...");
std::getchar();
return 0;
}

__________________________________________________ __________________





Here is the output I get:
__________________________________________________ __________________
Scope 1:

(0022FF30)-param_1::param_1()
(0022FF5F)-object::func1(123)
(0022FF30)-param_1::~param_1()


--------------------------------------------
Scope 2:

(0022FF30)-param_1::param_1()
(0022FF30)-param_1::~param_1()
(0022FF5F)-object::func1(123)


--------------------------------------------
Press <ENTER> to exit...

__________________________________________________ __________________




I am wondering why the const reference in 'Scope 2' (e.g., holder::m_fptr)
is getting destructed _before_ the call to 'h.m_fptr.execute()'? I thought
the output should be identical to that of 'Scope 1'... What exactly am I
doing wrong here? I am screwing something up somewhere... What can be done
to resolve this issue?


Yikes! ;^(...


Thanks.



--
Chris M. Thomasson
http://appcore.home.comcast.net

  Réponse avec citation
Vieux 08/04/2008, 22h24   #2
Victor Bazarov
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: lifetime of const references...

Chris Thomasson wrote:
> Here is the code which should compile fine; program output and my
> question follows:
> __________________________________________________ __________________
> #include <cstdio>
>
>
> namespace func_ptr {
> namespace sys {
> typedef void (callback_type) (void const* const);
>
> class base_pod {
> protected:
> callback_type* mp_callback;
>
> public:
> void execute() const {
> mp_callback(this);
> }
> };
>
> template<typename T, typename T_mfptr, typename T_p1>
> class param_1 : public base_pod{
> T m_obj;
> T_mfptr m_mfptr;
> T_p1 m_p1;
>
> public:
> param_1(T obj, T_mfptr mfptr, T_p1 p1)
> : m_obj(obj), m_mfptr(mfptr), m_p1(p1) {
> mp_callback = sys_callback;
> std::printf("(%p)-param_1::param_1()\n",
> reinterpret_cast<void*>(this));
> }
>
> ~param_1() throw() {
> std::printf("(%p)-param_1::~param_1()\n",
> reinterpret_cast<void*>(this));
> }
>
> private:
> void callback() const {
> (m_obj->*(m_mfptr))(m_p1);
> }
>
> static void sys_callback(void const* const state) {
> static_cast<param_1 const*>(state)->callback();
> }
> };
> }
>
>
> typedef sys::base_pod const& handle;
>
>
> template<typename T, typename T_mfptr, typename T_p1>
> sys::param_1<T, T_mfptr, T_p1>
> create(T _this, T_mfptr mfptr, T_p1 p1) {
> return sys::param_1<T, T_mfptr, T_p1>(_this, mfptr, p1);
> }
> }
>
>
> struct object {
> void func(int i) {
> std::printf("(%p)-object::func1(%d)\n",
> reinterpret_cast<void*>(this), i);
> }
> };
>
>
> struct holder {
> func_ptr::handle m_fptr;
> holder(func_ptr::handle fptr) : m_fptr(fptr) {}
> };
>
>
>
>
> int main() {
> object obj;
>
> {
> std::puts("Scope 1:\n");
> func_ptr::handle h(func_ptr::create(&obj, &object::func, 123));
> h.execute();
> }
>
> std::puts("\n\n--------------------------------------------");
>
> {
> std::puts("Scope 2:\n");
> holder h(func_ptr::create(&obj, &object::func, 123));
> h.m_fptr.execute();
> }
>
>
> /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~*/
> std::puts("\n\n--------------------------------------------\n\
> Press <ENTER> to exit...");
> std::getchar();
> return 0;
> }
>
> __________________________________________________ __________________
>
>
>
>
>
> Here is the output I get:
> __________________________________________________ __________________
> Scope 1:
>
> (0022FF30)-param_1::param_1()
> (0022FF5F)-object::func1(123)
> (0022FF30)-param_1::~param_1()
>
>
> --------------------------------------------
> Scope 2:
>
> (0022FF30)-param_1::param_1()
> (0022FF30)-param_1::~param_1()
> (0022FF5F)-object::func1(123)
>
>
> --------------------------------------------
> Press <ENTER> to exit...
>
> __________________________________________________ __________________
>
>
>
>
> I am wondering why the const reference in 'Scope 2' (e.g.,
> holder::m_fptr) is getting destructed _before_ the call to
> 'h.m_fptr.execute()'? I thought the output should be identical to
> that of 'Scope 1'... What exactly am I doing wrong here? I am
> screwing something up somewhere... What can be done to resolve this
> issue?
>
> Yikes! ;^(...


The difference is that in Scope 1 you're initialising a local variable
that has a reference to const type directly by a temporary. The life
of that temporary is extended to the end of the scope, but in Scope 2
you're initialising the reference to const that itself is an argument
to the c-tor, so the life of the temporary is limited to the expression
that is used to initialise the 'h' object. The member 'm_fptr' of the
'h' object (it's a reference that you copy-initialise from the argument)
becomes invalid as soon as the initialisation is complete. The temp
object is destroyed. A call to .execute() has undefined behaviour.

Here is the model of your code, in simpler terms:

#inlcude <iostream>
struct A {
void foo() { std::cout << "A::foo\n"; }
};

struct B {
A const &a;
B(A const &a) : a(a) {}
};

A makeA() { return A(); }

int main() {
{ // Scope 1
A const& ra(makeA());
ra.foo();
}

{ // Scope 2
B b(makeA()); // problem - the temporary dies here
b.a.roo(); // and here you're trying to use it
}
}

In my Scope 1 'ra' is a reference to the temporary object. In
my Scope 2 'b.a' is a reference to the temporary object, but it
is not initialised _directly_ by binding to the temporary, it's
_copy-initialised_ with a _temporary_ reference to A, which in
turn is bound to the temporary. The lifetime of the temporary
'A' in Scope 2 _would_ be extended if the reference (the argument
to the B's c-tor) survived beyond the initialisation expression.
It does not.

HTH

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


  Réponse avec citation
Vieux 08/04/2008, 23h58   #3
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: lifetime of const references...

"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:ftgnqh$sn8$1@news.datemas.de...
> Chris Thomasson wrote:
>> Here is the code which should compile fine; program output and my
>> question follows:
>> __________________________________________________ __________________

[...]
>> __________________________________________________ __________________
>>
>>
>>
>>
>> I am wondering why the const reference in 'Scope 2' (e.g.,
>> holder::m_fptr) is getting destructed _before_ the call to
>> 'h.m_fptr.execute()'? I thought the output should be identical to
>> that of 'Scope 1'... What exactly am I doing wrong here? I am
>> screwing something up somewhere... What can be done to resolve this
>> issue?
>>
>> Yikes! ;^(...

>
> The difference is that in Scope 1 you're initialising a local variable
> that has a reference to const type directly by a temporary. The life
> of that temporary is extended to the end of the scope, but in Scope 2
> you're initialising the reference to const that itself is an argument
> to the c-tor, so the life of the temporary is limited to the expression
> that is used to initialise the 'h' object. The member 'm_fptr' of the
> 'h' object (it's a reference that you copy-initialise from the argument)
> becomes invalid as soon as the initialisation is complete. The temp
> object is destroyed. A call to .execute() has undefined behaviour.

[...]

Ahh. Okay. For some reason I was erroneously thinking that the lifetime of
the const-reference would somehow be "extended" across the copy-initialize
and finally into the 'holder::m_fptr' member variable, and only be destroyed
when the 'holder' object was finally destructed.

Thanks for the lesson!

:^)

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 05h27.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,12933 seconds with 11 queries