Topic: Derived class constructors


Author: "John Smith" <jraft@home.com>
Date: 1999/09/23
Raw View
I see nothing wrong with the following depending on Nader's precise needs
(this is streamlined for brevity). Certainly something for him to think
about.

class Base
{
public:
     Base() : count(0)
     {
          // Initializing "x" would also be a good idea here (probably to
zeros)
     }

     Base(int Param0, ...)
     {
          va_list ArgPtr;
          va_start(ArgPtr, Param0);
          Init(Param0, ArgPtr);
          va_end(ArgPtr);
     }

protected:
     void Init(int Param0, va_list ArgPtr)
     {
          int p = Param0;
          count = 0;

          while( p != 0 )
          {
               x[count++] = p;
               p = va_arg(ArgPtr, int);
          }
     }

private:
     int x[10];
     int count;
};

class Derived : public Base
{
public:
     Derived(int Param0, ...)
     {
          va_list ArgPtr;
          va_start(ArgPtr, Param0);
          Base::Init(Param0, ArgPtr);
          va_end(ArgPtr);
     }
};
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/09/22
Raw View
"John Smith" <jraft@home.com> writes:

>> >I have question: How may a derived class constructor try to initiate the
>> >base class's constructor while both of the constructors have a parameters
>> >looking like this (param ,...)  -namely variable argument list?

>Another solution in addition to the one from Steve is to simply use
>"vsprintf()" in the body of the derived class constructor and pass the
>results to some (protected) base class function set up for this purpose. In
>other words, let the base class' default constructor do its thing and in the
>derived class constructor simply invoke this protected function, passing the
>results from "vsprintf()").

That does not solve the initialization problem. If you don't need
to initialize the base class with the derived-class constructor
arguments, you can just use the <stdarg> macros in the constructor
body.

If you do need to initialize the base-class constructor with
derived-class constructor arguments, there is no mechanism for
the derived-class constructor to do what you suggest. That is,
you can't pass the arguments to a base-class constructor from
inside the derived-class constructor body.

--
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "John Smith" <jraft@home.com>
Date: 1999/09/23
Raw View
To the moderator: This is a follow-up to the post which I just sent 5
minutes ago and should be posted right after it (if it's approved). Thanks.

[ moderator's note: As explained in the FAQ, different posts can
  get sent to different moderators, who are in differnt parts of
  the world. (North America, Europe, Australia). There is no way
  to predict which moderator will receive which post, or how
  long it will take to get approved, or how long it will take
  to propagate after approval.  -sdc ]

I should point out that this solution is slightly different than what I had
first proposed (which involved "vsprintf()"). It's what I meant however so
your response was reasonable. It's been at least 3 years since I last wrote
a routine with variable arguments so I was doing it from memory. I should
have quickly checked my facts before posting (obviously "vsprintf()" was not
required).



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "John Smith" <jraft@home.com>
Date: 1999/09/22
Raw View
> >I have question: How may a derived class constructor try to initiate the
> >base class's constructor while both of the constructors have a parameters
> >looking like this (param ,...)  -namely variable argument list?

Another solution in addition to the one from Steve is to simply use
"vsprintf()" in the body of the derived class constructor and pass the
results to some (protected) base class function set up for this purpose. In
other words, let the base class' default constructor do its thing and in the
derived class constructor simply invoke this protected function, passing the
results from "vsprintf()"). I think this might be the cleaner approach since
it involves no intermediate class the user need be aware of (as suggested by
Steve). There are some possible inefficiencies however but they may be
tolerable depending on your classes. For instance, since the base class
default constructor will be invoked, it may initialize (perhaps expensively)
some local data which is just going to get re-initialized again anyway once
this protected function is ultimately called. I think however this is an
all-around good approach. Food for thought.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Nader Nejadhashemi" <nader_nh@hotmail.com>
Date: 1999/09/18
Raw View

Hi all;

I have question: How may a derived class constructor try to initiate the
base class's constructor while both of the constructors have a parameters
looking like this (param ,...)  -namely variable argument list?

To make it more clear take a look at the following:

// == base class ==
class base
{
public:
    int x[10];
    int count;
    base(int param0, ...); // constructor declaration
};

// == derived class ==
class derived: public base
{
public:
    int y[10];
    derived(int param0, ...);
};

// == base constructor ==
base::base(int param0, ...)
{
    int p;
    va_list args;

    count = 0;
    va_start(args, param0);
    p = param0;
    while( p != 0 )
    {
        x[count++] = p;
        p = va_arg(args, int);
    }
    va_end(arg );
}

// == derived constructor ==
derived::derived(int param0, ...) : base (param0, ???)
/*  instead of ??? one should be able to send the same list of
 |  parameters that are passed to the derived constructor.
 */ The question is how.
{
    for (int i = 0; i < count; ++ i)
        y[i] = x[i];
}

// == Main program ==
int main(int argc, char* argv[])
{
    derived  dvar(1,2,3,4,5,6,7,8,9,0);

    for (int i=0; i < dvar.count; ++ i)
        printf ("\n %d", dvar.y[i]);
}
--


/Nader.
---------------------------           ________
Nader Nejadhashemi            o      |   __   |
35 Marshall St., Apt.# 1102     \_ O |  |__|  |
Richmond Hill,               ____/ \ |___WW___|
Ontario L4C 0A5, CANADA.     __/   /     ||
Tel: (905) 770-2229                      ||
---------------------------              ||
                            _____________||______________




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/09/18
Raw View
"Nader Nejadhashemi" <nader_nh@hotmail.com> writes:

>I have question: How may a derived class constructor try to initiate the
>base class's constructor while both of the constructors have a parameters
>looking like this (param ,...)  -namely variable argument list?

You can't do it directly. The only way to access a variable
argument list is inside the called function, using the <stdarg.h>
macros.  By the time you have entered the derived-class constructor
body, it is too late to initialize the base class.

Consider using an auxialiary class or container that holds the
variable number of values or objects. Use that to intialize
your classes.

Example: Instead of

class base {
public:
    base(int param_count, ...);
};

Try this:

struct int_list {
 int_list(int param_count, ...) { copy params into data }
 vector<int> data;
};

class base {
public:
    base(const int_list& l);
};


class derived: public base {
public:
    derived(const int_list& l) : base(l) { ... }
};

--
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]