can't remember

L

LuB

Bruce Sutter talks about this a bit - but I can't remember where. When
is it safe to use an object or reference to an object. When does it
have an accessible address?

Specifically, I think it has to pass out of the out initialization
stage ... but I can't remember exactly. Can anyone clarify?

Safety aside, is this undefined - passing B to A's ctor before B has
completed initialization?

Thanks in advance,

-Luther

/////////////////////////////////////////////////////

#include <iostream>

template<typename BType>
class A
{

public:
A(const BType& b) : b_(b) { std::cout << "A ctor" << std::endl; }

private:
const BType& b_;

};

class B
{

public:
B() : a_(*this) { std::cout << "B ctor" << std::endl; }

private:
const A<B>& a_;

};

int
main(int argc, char** argv)
{

B b;
std::cout << "hello world" << std::endl;
}
 
M

mlimber

LuB said:
Bruce Sutter talks about this a bit - but I can't remember where. When
is it safe to use an object or reference to an object. When does it
have an accessible address?

Specifically, I think it has to pass out of the out initialization
stage ... but I can't remember exactly. Can anyone clarify?

I think you've also mistaken Bruce Sutter for Herb Sutter, but you can
search his website for the topic. Here's one that might be what you're
looking for:

http://www.gotw.ca/publications/mill13.htm

The [this] pointer is valid and points to the storage allocated for the
object when the constructor starts (compare what happens with when you
call operator new:
http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14), and using
it is legitimate.

However, an object's lifetime has not begun until the constructor
successfully completes, and indeed, were that object's constructor to
throw an exception, the memory allocated for it would be deallocated,
and any reference to it would be dangling, which, if used, leads to
undefined behavior.
Safety aside, is this undefined - passing B to A's ctor before B has
completed initialization?

Thanks in advance,

-Luther

/////////////////////////////////////////////////////

#include <iostream>

template<typename BType>
class A
{

public:
A(const BType& b) : b_(b) { std::cout << "A ctor" << std::endl; }

private:
const BType& b_;

};

class B
{

public:
B() : a_(*this) { std::cout << "B ctor" << std::endl; }

private:
const A<B>& a_;

I'll assume you didn't want the reference here. Otherwise, it wouldn't
compile.
};

int
main(int argc, char** argv)
{

B b;
std::cout << "hello world" << std::endl;
}

That code could lead to undefined behavior (though it doesn't as
written). A is itself a member of B (if you delete the reference, as I
suggested) and would be destructed after B::~B() executes, but if A
tried to use its reference to B either in its constructor or destructor
to access other data members of B, you could get undefined behavior if
those part(s) of B had already been destroyed. That of course depends
on the construction/destruction order of B's members.

Cheers! --M
 
L

LuB

Eye yai yai ... I guess Bruce Sutter was a pitcher for the Cardinals
here in St. Louis ... ;-)

And many thanks for your answer. Helped me better understand the
potential danger of the idiom.

Thanks again,

-Luther
 

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

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top