By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
426,248 Members | 1,979 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 426,248 IT Pros & Developers. It's quick & easy.

How to call a constructor from a constructor

P: n/a
Hi,

I have the following class. I want the constructor gnuplot_2d(int size)
has the same behavior as if I call from the 2-argument constructor
gnuplot_2d(size, size). But the following definition doesn't work. Do
you have any idea?

Although I can define
template <typename __Tp>
gnuplot_2d<__Tp>::gnuplot_2d(int size) : _size_x(size),_size_y(size){
}
, it will be cumbersome if there are a lot of code in the function
body.

Best wishes,
Peng

template <typename __Tp>
class gnuplot_2d {
public:
gnuplot_2d(int size);
gnuplot_2d(int size_x, int size_y);
~gnuplot_2d(){};
private:
int _size_x;
int _size_y;
};

template <typename __Tp>
gnuplot_2d<__Tp>::gnuplot_2d(int size) : gnuplot_2d<__Tp>(size, size){
}

template <typename __Tp>
gnuplot_2d<__Tp>::gnuplot_2d(int size_x, int size_y) :
_size_x(size_x),_size_y(size_y){
}

Jul 23 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Pe*******@gmail.com wrote:
Hi,

I have the following class. I want the constructor gnuplot_2d(int size)
has the same behavior as if I call from the 2-argument constructor
gnuplot_2d(size, size). But the following definition doesn't work. Do
you have any idea?

Although I can define
template <typename __Tp>
gnuplot_2d<__Tp>::gnuplot_2d(int size) : _size_x(size),_size_y(size){
}
, it will be cumbersome if there are a lot of code in the function
body.

Best wishes,
Peng

template <typename __Tp>
class gnuplot_2d {
public:
gnuplot_2d(int size);
gnuplot_2d(int size_x, int size_y);
~gnuplot_2d(){};
private:
int _size_x;
int _size_y;
};

template <typename __Tp>
gnuplot_2d<__Tp>::gnuplot_2d(int size) : gnuplot_2d<__Tp>(size, size){
}

template <typename __Tp>
gnuplot_2d<__Tp>::gnuplot_2d(int size_x, int size_y) :
_size_x(size_x),_size_y(size_y){
}


Why not just do the following, or is there more to the
problem than you have stated?

template <typename __Tp>
gnuplot_2d<__Tp>::gnuplot_2d(int size) :
_size_x(size), _size_y(size){
}
Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Jul 23 '05 #2

P: n/a
As I said in the first message, suppose there are a long chunk of code
in the body of the definition of gnuplot_2d<__Tp>::gnuplot_2d(int
size_x, int size_y), you have to copy all the same code to the
definition of gnuplot_2d<__Tp>::gnuplot_2d(int size).

If you do that you create some problem to maintain the code. Suppose
later on you change the definition of gnuplot_2d(int size_x, int
size_y) a little bit, you have to change the definition of
nuplot_2d(int size) manually to make sure consistency.

I want a better solution to this problem. Thanks!

Best wishes,
Peng

Jul 23 '05 #3

P: n/a
Pe*******@gmail.com wrote:
As I said in the first message, suppose there are a long chunk of code
in the body of the definition of gnuplot_2d<__Tp>::gnuplot_2d(int
size_x, int size_y), you have to copy all the same code to the
definition of gnuplot_2d<__Tp>::gnuplot_2d(int size).

If you do that you create some problem to maintain the code. Suppose
later on you change the definition of gnuplot_2d(int size_x, int
size_y) a little bit, you have to change the definition of
nuplot_2d(int size) manually to make sure consistency.

I want a better solution to this problem. Thanks!

Best wishes,
Peng


If the constructors are complex, one approach is to factor
out the code common to all of the constructors (and often
the assignment operator) into a private function that each
of the constructors calls. Here's an incomplete example:

class A
{
public:
A() { doinit(0, 0); }
A(int x) { doinit(x, x); }
A(int x, int y) { doinit(x, y); }
private: // or protected
void doinit(int x, int y)
{
/* does complex stuff used by all constructors */
}
};

Regards,
Larry
--
Anti-spam address, change each 'X' to '.' to reply directly.
Jul 23 '05 #4

P: n/a
So call a constructor from another constructor is impossible, right?

Thanks,
Peng

Jul 23 '05 #5

P: n/a
* Pe*******@gmail.com:

So call a constructor from another constructor is impossible, right?


The question seems to have some invalid assumptions, i.e., meaningless.

To call a constructor of class T on an object being constructed you'll have
to do use very dirty techniques and you'll be throwing overboard all the help
that the language normally gives you, just like when using a void* pointer;
it's not a good idea.

One clean solution to your problem is, instead,

template <typename Tp>
class gnuplot_2d_impl
{
gnuplot_2d_impl( int width, int height )
:
myWidth( width ), myHeight( myHeight )
{
// Lots of code here.
}
};

template <typename Tp>
class gnuplot_2d: private gnuplot_2d_impl
{
gnuplot_2d( int size ): gnuplot_2d_impl( size, size )
{}

gnuplot_2d( int width, int height ): gnuplot_2d_impl( width, height )
{}
};

Here the constructor calls are via the mechanism that C++ offers for calling
constructors from constructors: constructor initalizer lists.

Btw., note that two successive underscores are not allowed in C++ identifiers.

Neither is an underscore followed by an uppercase letter.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #6

P: n/a
Pe*******@gmail.com wrote:
So call a constructor from another constructor is impossible, right?

You can't call constructors period. They are automatically invoked
for you as part of object creation. Other than the overloading choices
there isn't much you can do to affect their use.

As we've told you before, put the common code in a member function that
you CAN call.
Jul 23 '05 #7

P: n/a
> As I said in the first message, suppose there are a long chunk of code
in the body of the definition of gnuplot_2d<__Tp>::gnuplot_2d(int
size_x, int size_y), you have to copy all the same code to the
definition of gnuplot_2d<__Tp>::gnuplot_2d(int size).

If you do that you create some problem to maintain the code. Suppose
later on you change the definition of gnuplot_2d(int size_x, int
size_y) a little bit, you have to change the definition of
nuplot_2d(int size) manually to make sure consistency.

I want a better solution to this problem. Thanks!


You can use placement new. For example:

class N
{
public:
N(int a, int b) : x(a), y(b) {};
N(int c) { new (this) N(c, c); };
N() { new (this) N(0); };

int x, y;
};

vc7.1 optimises these equivalent to writing:

class N
{
public:
N(int a, int b) : x(a), y(b) {};
N(int c) { if(this) { x = c; y = c; }; };
N() { if(this) { x = 0; y = 0; }; };

int x, y;
};

You might be able to eliminate the if statments by writing your own
placement new operator.

Regards,
cadull
Jul 23 '05 #8

P: n/a
But, if you are using the above approach, i.e placement new, be sure to
call desturctor explicitely.

But here , there are two ways by which class can get generated, one
that uses placement new and one that does not. In one case u need to
call dtor explicitely and the other case you need not.

But, calling the dtor explicitely in both the cases may be harm less as
we really can not know (with out a ugly global/member varibale) how the
object got created at first place

Jul 23 '05 #9

P: n/a
<Pe*******@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
So call a constructor from another constructor is impossible, right?


Simple answer: right. It's impossible.

- JFA1
Jul 23 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.