www.digitalmars.com         C & C++   DMDScript  

c++ - lost values from one constructor to another

reply Carlos Santander B. <Carlos_member pathlink.com> writes:
The following code:

#include <stdio.h>

class A {
int a;
public:
A() { A(4); printf("%d\n",a); }
A(int b) { a=b; printf("%d,",a); }
};
void main() { A x; }

outputs: 4,4219774. Can somebody explain me why?

Ok, maybe the example is too trivial and I could do A(int b=4), but that's not
the exact case. And even if it was, this should still work, shouldn't it?
Jul 23 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
That's not the way C++ works

In your example, the first constructor creates an instance who's a member is
not initialised to any meaningful value, hence 4219774 is as reasonable as
any other value.

What you appear to be trying to do is to have one constructor call another.
IMSC Java does allow this. C++ does not.

There are two ways to do it in C++, and the choice of which you want to do
depends on the constraints of efficiency and maintainability.

You could defer to an intermediate function, e.g.

class A
{
// Construction
public:
    A()
        : a(_init(0))
    {}
    A(int b)
        : a(_init(b))
    {}

// Implementation
private:
    int _pre_init(int i)
    {
        printf("%d\n", i);
        return i;
    }

// Members
public or private here, your choice:
    int    a;
}

Given that this is a very simple example, this looks very contrived, but
this technique does find its uses in real cases. The advantages are that you
only have to write the code once; when it's complex this reduces the
maintenance burden, as well as producing smaller code.

The other alternative is to replicate the functionality in the two (or
however many) constructors, sacrificing code size and maintainability for
runtime efficiency. (And yes, everyone, larger code can in fact reduce
runtime speed due to cache misses; it's a tradeoff thing.)

class A
{
// Construction
public:
    A()
        : a(0)
    {
        printf("%d\n", a); // If you change this, then ...
    }
    A(int b)
        : a(b)
    {
        printf("%d\n", a); // ... don't forget to change this accordingly!!
    }

// Members
public or private here, your choice:
    int    a;
}

Alas, as with most things in SE, the answer is: it depends. The choice is
yours.

"Carlos Santander B." <Carlos_member pathlink.com> wrote in message
news:bfnjdh$2r1a$1 digitaldaemon.com...
 The following code:

 #include <stdio.h>

 class A {
 int a;
 public:
 A() { A(4); printf("%d\n",a); }
 A(int b) { a=b; printf("%d,",a); }
 };
 void main() { A x; }

 outputs: 4,4219774. Can somebody explain me why?

 Ok, maybe the example is too trivial and I could do A(int b=4), but that's
not
 the exact case. And even if it was, this should still work, shouldn't it?
Jul 23 2003
parent Carlos Santander B. <Carlos_member pathlink.com> writes:
Thanks! Things I never learnt about C++, and that I find so often in D...

Anyway, another way to do it would be having, instead of a basic constructor, a
basic initialization function for the same purpose, right?

In article <bfnlut$2toj$1 digitaldaemon.com>, Matthew Wilson says...
That's not the way C++ works

In your example, the first constructor creates an instance who's a member is
not initialised to any meaningful value, hence 4219774 is as reasonable as
any other value.

What you appear to be trying to do is to have one constructor call another.
IMSC Java does allow this. C++ does not.

There are two ways to do it in C++, and the choice of which you want to do
depends on the constraints of efficiency and maintainability.

You could defer to an intermediate function, e.g.

class A
{
// Construction
public:
    A()
        : a(_init(0))
    {}
    A(int b)
        : a(_init(b))
    {}

// Implementation
private:
    int _pre_init(int i)
    {
        printf("%d\n", i);
        return i;
    }

// Members
public or private here, your choice:
    int    a;
}

Given that this is a very simple example, this looks very contrived, but
this technique does find its uses in real cases. The advantages are that you
only have to write the code once; when it's complex this reduces the
maintenance burden, as well as producing smaller code.

The other alternative is to replicate the functionality in the two (or
however many) constructors, sacrificing code size and maintainability for
runtime efficiency. (And yes, everyone, larger code can in fact reduce
runtime speed due to cache misses; it's a tradeoff thing.)

class A
{
// Construction
public:
    A()
        : a(0)
    {
        printf("%d\n", a); // If you change this, then ...
    }
    A(int b)
        : a(b)
    {
        printf("%d\n", a); // ... don't forget to change this accordingly!!
    }

// Members
public or private here, your choice:
    int    a;
}

Alas, as with most things in SE, the answer is: it depends. The choice is
yours.
Jul 24 2003