Topic: recursive constructor


Author: "Ruslan Abdikeev" <ruslan_abdikeevRemoveIt@hotmail.com>
Date: Thu, 29 Mar 2001 12:59:17 CST
Raw View
Greg,

In both you examples,

> class X
> {
> public:
>    X(int i) ;
>    X(void) : X(1) {}
> };

and

> class X
> {
> public:
>    X(int i)  : X(i-1) {}
> };

you are using the name of the class under construction as the
'mem-initializer-id' (12.6.2/1).
It seems to me that it is NOT correct and shall not compile, because X is
not a name of "non-static data member, or a direct  or virtual base of
constructor's class".


Sincerely,

Ruslan Abdikeev
Brainbench MVP for Visual C++
http://www.brainbench.com



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Greg Brewer" <nospam.greg@brewer.net>
Date: Fri, 30 Mar 2001 22:09:46 GMT
Raw View
"Ruslan Abdikeev" <ruslan_abdikeevRemoveIt@hotmail.com> wrote in message
news:99vvn8$4eb$1@news.wplus.spb.ru...
> you are using the name of the class under construction as the
> 'mem-initializer-id' (12.6.2/1).
> It seems to me that it is NOT correct and shall not compile, because X is
> not a name of "non-static data member, or a direct  or virtual base of
> constructor's class".

Never said it would compile!  Simply presented it as an example of a
recursive call to the constructor.  I've often had a long list of items that
had to be initialized by the constructor (eg a reference pointer).  When the
constructor is overloaded, this means lots of duplicate code.  I was
guessing this is what was actually desired.

Greg


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cuneyt arkin <s_teksoy@yahoo.com>
Date: Tue, 27 Mar 2001 07:04:38 CST
Raw View
Can a constructor be called recursively (obviously, *not* on the
same object) during the initialization of the object, according
to The Standard? For example, is the piece of code below
valid c++ ?

class X
{
    unsigned int n;
public:
    X(int);
    unsigned int get() {return n;}
};

X::X(int i)
{
    if (i <= 1)
        n = 1;
    else
    {
        X a(i - 1);  // line 15
        n = i * a.get();
    }
}

I think the line 15 is an explicit initialization (12.6.1).
12.6.1/1 says that "...Either direct-initialization semantics or
copy-initialization semantics apply; see 8.5". Since its form is
equivalent to "T x(a);" then direct-initialization semantics must
apply (8.5/12) (?). 8.5/14 says that "If the initialization is
direct initialization [...] The constructor so selected is called
to initialize the object, with the initializer expression(s) as its
argument(s)". Since the constructor is called then the 5.2.2 must
apply (??). (If this is not correct, what semantics apply to a
constructor being called??) 5.2.2/9 says "Recursive calls are
permitted, except to the function named main", then a constructor
can be called recursively (?). That's my $0.02.

Is my reasoning flawed? If it is, could anyone provide a correct
(or shorter) reasoning to decide whether a constructor can be
called recursively? (That is, the same constructor is being
called from itself, on a different object of the same class)

I would appreciate an answer.

regards,

_____________________________________________________________________
This message has been checked for all known viruses by the
MessageLabs Virus Control Centre. For further information visit
http://www.messagelabs.com/stats.asp

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 27 Mar 2001 12:50:41 CST
Raw View
cuneyt arkin wrote:
>
> Can a constructor be called recursively (obviously, *not* on the
> same object) during the initialization of the object, according
> to The Standard? For example, is the piece of code below
> valid c++ ?
>
> class X
> {
>     unsigned int n;
> public:
>     X(int);
>     unsigned int get() {return n;}
> };
>
> X::X(int i)
> {
>     if (i <= 1)
>         n = 1;
>     else
>     {
>         X a(i - 1);  // line 15
>         n = i * a.get();
>     }
> }

Yes. Do you have any particular reason for thinking that it might not
be?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Edward Diener <eddielee@tropicsoft.com>
Date: Tue, 27 Mar 2001 16:32:55 CST
Raw View
cuneyt arkin wrote:

> Can a constructor be called recursively (obviously, *not* on the
> same object) during the initialization of the object, according
> to The Standard? For example, is the piece of code below
> valid c++ ?
>
> class X
> {
>     unsigned int n;
> public:
>     X(int);
>     unsigned int get() {return n;}
> };
>
> X::X(int i)
> {
>     if (i <= 1)
>         n = 1;
>     else
>     {
>         X a(i - 1);  // line 15
>         n = i * a.get();
>     }
> }

Line 15 is perfectly valid but you aren't really calling the constructor
recursively. Instead you are constructing another object of the same type
from within the constructor. Recursiveness would occur if you were able to
call X::X(int i) from within X::X(int i) on the same object, but you can't do
that in C++ with constructors, although you can of course with other member
functions.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 27 Mar 2001 16:33:12 CST
Raw View
In article <3AC025CA.6588BD07@yahoo.com>, cuneyt arkin
<s_teksoy@yahoo.com> writes
>Is my reasoning flawed? If it is, could anyone provide a correct
>(or shorter) reasoning to decide whether a constructor can be
>called recursively? (That is, the same constructor is being
>called from itself, on a different object of the same class)
>
>I would appreciate an answer.
What was the question? I don't think we ever said you could not do this,
just that it does not make much sense in real code.


--
Francis Glassborow
See http://www.accu.org for details of The ACCU Spring Conference, 2001
(includes many regular participants to C & C++ newsgroups)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Greg Brewer" <nospam.greg@brewer.net>
Date: Tue, 27 Mar 2001 16:37:37 CST
Raw View
You aren't calling the constructor recursively -- at least not in a direct
sense.  You are recursively creating the object which indirectly calls the
constructor.

Usually, when people want to recursively call the constructor, they mean do
something like
class X
{
public:
   X(int i) ;
   X(void) : X(1) {}
};

which isn't exactly recursive either.  However,
class X
{
public:
   X(int i)  : X(i-1) {}
};

would be recursive and guarenteed to be infinite.  If fact, I don't think
there is anyway to code it so that it won't be infinite.

Greg



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Tue, 27 Mar 2001 16:37:33 CST
Raw View
"cuneyt arkin" <s_teksoy@yahoo.com> wrote in message
news:3AC025CA.6588BD07@yahoo.com...
>
> Can a constructor be called recursively (obviously, *not* on the
> same object) during the initialization of the object, according
> to The Standard? For example, is the piece of code below
> valid c++ ?
>
> class X
> {
>     unsigned int n;
> public:
>     X(int);
>     unsigned int get() {return n;}
> };
>
> X::X(int i)
> {
>     if (i <= 1)
>         n = 1;
>     else
>     {
>         X a(i - 1);  // line 15
>         n = i * a.get();
>     }
> }
>
> I think the line 15 is an explicit initialization (12.6.1).
> 12.6.1/1 says that "...Either direct-initialization semantics or
> copy-initialization semantics apply; see 8.5". Since its form is
> equivalent to "T x(a);" then direct-initialization semantics must
> apply (8.5/12) (?). 8.5/14 says that "If the initialization is
> direct initialization [...] The constructor so selected is called
> to initialize the object, with the initializer expression(s) as its
> argument(s)". Since the constructor is called then the 5.2.2 must
> apply (??). (If this is not correct, what semantics apply to a
> constructor being called??) 5.2.2/9 says "Recursive calls are
> permitted, except to the function named main", then a constructor
> can be called recursively (?). That's my $0.02.
>
> Is my reasoning flawed? If it is, could anyone provide a correct
> (or shorter) reasoning to decide whether a constructor can be
> called recursively? (That is, the same constructor is being
> called from itself, on a different object of the same class)
>
> I would appreciate an answer.

Your code is legal. For i<=1 it is a simple constructor. For i>1 it will
construct a helper object of the same type, with a different value of i,
which it will then use to initialize the member variable n. This is
perfectly valid.

Since the same constructor is called for the helper object, and this is done
before the completion of the current constructor, the constructor is "called
recursively" as you describe it, and it will correctly store i-factorial as
the value of n.

The important difference between this, and a "proper" recursive call in a
member function is that if a member function recurses, the object it refers
to is the same, and modifications to it persist after each layer of
recursion exits, whereas in this case the "recursive" call constructs a new
object and has no access to the data of the original object.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]