Constructor & default arguments

T

The Directive

This code will not compiled:

In main function:

Dot temp = new Dot( *(new Point( 5, 5 )) );

In Dot class:

//Constructor with default arguments.
Dot::Dot( Point& point= *(new Point( 5, 5 )),
Color& color = *(new Color( 100, 125, 106 )) )
{
}

It complains that:

Main.cpp
[Warning] In function `int main(int, char**)':
Main.cpp
no matching function for call to `Dot::Dot(Point&)'
Dot.h
candidates are: Dot::Dot(Dot&)
Dot.h
Dot::Dot(Point&, Color&)
Main.o(.text+0x84)
[Warning] In function `main':
[Linker error] undefined reference to `Dot::Dot()'

I'm using DEV-C++ and gcc.

Why doesn't it find the matching constructor:

Dot::Dot(Point&, Color&)

--The Directive
 
R

Ron Natalie

The Directive said:
This code will not compiled:

In main function:

Dot temp = new Dot( *(new Point( 5, 5 )) );

In Dot class:

//Constructor with default arguments.
Dot::Dot( Point& point= *(new Point( 5, 5 )),
Color& color = *(new Color( 100, 125, 106 )) )
{
}

I can't tell for sure with the snippet you've provided, but I suspect that at the point
where the "new Dot(..." is executed you haven't provided the default arguments yet.
The declaration with the defaulted arguments must be seen before the place it is used.
For example:

void func(int);

func();

void func(int x = 3) { }

won't compile because at the point func() is called, it hasn't seen the default values for
the arguments.
 
K

Kevin Saff

The Directive said:
This code will not compiled:

In main function:

Dot temp = new Dot( *(new Point( 5, 5 )) );

temp is of type "Dot", but you are trying to assign a Dot* (which is what
"new Dot" returns) to it.

Instead, the correct way to call a constructor might be:

Dot temp (*new Point (5, 5));

Code involving "*new" usually leads to memory leaks! You will need to
forget many Java habits. Do you have a decent C++ book?
In Dot class:

// Constructor with default arguments.
Dot::Dot( Point& point= *(new Point( 5, 5 )),
Color& color = *(new Color( 100, 125, 106 )) )
{
}

First of all, you can only define default arguments in the function
declaration. (inside your class for a constructor).

Also, you're using *new again. In C++ you never use "new" without later
using "delete", since C++ does not have garbage collection. Since you don't
actually store the pointers here, you can't delete them, and you will get a
memory leak any time you use the default arguments.
It complains that:

Main.cpp
[Warning] In function `int main(int, char**)':
Main.cpp
no matching function for call to `Dot::Dot(Point&)'
Dot.h
candidates are: Dot::Dot(Dot&)
Dot.h
Dot::Dot(Point&, Color&)
Main.o(.text+0x84)
[Warning] In function `main':
[Linker error] undefined reference to `Dot::Dot()'

I'm using DEV-C++ and gcc.

Why doesn't it find the matching constructor:

Dot::Dot(Point&, Color&)

It's hard to tell without more complete code.
--The Directive

HTH
 
P

Peter Koch Larsen

The Directive said:
This code will not compiled:

In main function:

Dot temp = new Dot( *(new Point( 5, 5 )) );

In Dot class:

//Constructor with default arguments.
Dot::Dot( Point& point= *(new Point( 5, 5 )),
Color& color = *(new Color( 100, 125, 106 )) )
{
}

It complains that:

Main.cpp
[Warning] In function `int main(int, char**)':
Main.cpp
no matching function for call to `Dot::Dot(Point&)'
Dot.h
candidates are: Dot::Dot(Dot&)
Dot.h
Dot::Dot(Point&, Color&)
Main.o(.text+0x84)
[Warning] In function `main':
[Linker error] undefined reference to `Dot::Dot()'

I'm using DEV-C++ and gcc.

Why doesn't it find the matching constructor:

Dot::Dot(Point&, Color&)

--The Directive

That code is just so shockfull of errors, I must recommend that you

a) forget about Java when coding C++.
b) learn about C++ - in particular when to use new and const correctness.

One link for you: http://www.parashift.com/C++-faq-lite

Kind regards
Peter
 
K

Kevin Goodsell

Robert Paul Clark wrote:
<top-posted stuff>

You've posted a whole bunch of top-posted messages now. Could you please
stop that? It's very irritating.

-Kevin
 
T

The Directive

[Snipped]
I can't tell for sure with the snippet you've provided, but I suspect that at the point
where the "new Dot(..." is executed you haven't provided the default arguments yet.
The declaration with the defaulted arguments must be seen before the place it is used.
For example:

void func(int);

func();

void func(int x = 3) { }

won't compile because at the point func() is called, it hasn't seen the default values for
the arguments.

Ron,

You hit the nail on the head.

--The Directive
 
T

The Directive

Kevin Saff said:
temp is of type "Dot", but you are trying to assign a Dot* (which is what
"new Dot" returns) to it.

This was a typo when posting the code.
Instead, the correct way to call a constructor might be:

Dot temp (*new Point (5, 5));

Code involving "*new" usually leads to memory leaks! You will need to
forget many Java habits. Do you have a decent C++ book?


First of all, you can only define default arguments in the function
declaration. (inside your class for a constructor).

Your statement is incorrect or I don't comprehend what you're stating:

#include <iostream>
#include <stdlib.h>

using namespace std;

class base
{
public:

void function (int);
};

void base::function (int temp = 4)
{
cout << temp << "\n";
}

int main(int argc, char *argv[])
{
base temp;

temp.function();
temp.function(7);

system("PAUSE");
return 0;
}

The code compiles, runs, and does what it's suppose to do.

However, the following version of the previous program doesn't work:

#include <iostream>
#include <stdlib.h>

using namespace std;

class base
{
public:

void function (int);
};

int main(int argc, char *argv[])
{
base temp;

temp.function();
temp.function(7);

system("PAUSE");
return 0;
}

void base::function (int temp = 4)
{
cout << temp << "\n";
}

which surprises me that the compiler (or the C++ standard) is
not smart enough to compile this version of the program.
Also, you're using *new again. In C++ you never use "new" without later
using "delete", since C++ does not have garbage collection. Since you don't
actually store the pointers here, you can't delete them, and you will get a
memory leak any time you use the default arguments.

When I post code, I usually only post a portion or fragments of the
true code to make it easy to illustrate my question.

--The Directive
 
T

The Directive

[Snipped]
That code is just so shockfull of errors, I must recommend that you

a) forget about Java when coding C++.
b) learn about C++ - in particular when to use new and const correctness.

I did learn about C++. I'm now putting into practice what I've
learned. That's part of learning also. Writing c++ sample code
clarifies my C++ knowlege and expands it.

I understood people responses about the pointer typo, new/delete
usage, and default arguments. What do you specifically mean by "const
correctness."?
One link for you: http://www.parashift.com/C++-faq-lite

Kind regards
Peter

--The Directive
 
K

Karl Heinz Buchegger

The said:
First of all, you can only define default arguments in the function

Your statement is incorrect or I don't comprehend what you're stating:

Not at all:

8.3.6 Default arguments

3 A default argument expression shall be specified only in the
parameter-declaration-clause of a function declaration or in
a template-parameter.

[snip example 1]
The code compiles, runs, and does what it's suppose to do.

.... but is still illegal.

[snip example 2]
which surprises me that the compiler (or the C++ standard) is
not smart enough to compile this version of the program.

The compiler reads the source code from top to bottom. It never
steps back and corrects previously compiled code.

In

class base
{
public:
void function(int);
};

int main()
{
base temp;

temp.function();

the compiler expects you to provide an argument to function(). This
is what the declaration has told the compiler.
When I post code, I usually only post a portion or fragments of the
true code to make it easy to illustrate my question.

Then prepare that people will correct mistakes in your posting which
are not there in your true source code. If you do that often enough
(posting not the true code), people finally will stop correcting
your programs, since it is a waste of time to correct errors and
afterwards you are saying: it was only a typo in posting.
 
K

Karl Heinz Buchegger

Karl said:
Then prepare that people will correct mistakes in your posting which
are not there in your true source code. If you do that often enough
(posting not the true code), people finally will stop correcting
your programs, since it is a waste of time to correct errors and
afterwards you are saying: it was only a typo in posting.

Forget that last paragraph. I misread what you typed. You post
real code (using cut&paste), that's fine.

But still: using *new usually indicates a problem.
 
P

Peter Koch Larsen

The Directive said:
[Snipped]
That code is just so shockfull of errors, I must recommend that you

a) forget about Java when coding C++.
b) learn about C++ - in particular when to use new and const
correctness.

I did learn about C++. I'm now putting into practice what I've
learned. That's part of learning also. Writing c++ sample code
clarifies my C++ knowlege and expands it.

I understood people responses about the pointer typo, new/delete
usage, and default arguments. What do you specifically mean by "const
correctness."?
One link for you: http://www.parashift.com/C++-faq-lite

Kind regards
Peter

--The Directive

Ok - I'll bite. Here is your original code:

Dot temp = new Dot( *(new Point( 5, 5 )) );

Your first confusion (Java-inspired):

In C++
a) whenever you use new to create some variable (e.g. an object), you must
use delete to reclaim the space allocated. C++ does not have
garbage-collection, so you are leaking memory.
b) new does not return an object, but a pointer to one. Thus, the code above
would not compile (you can't normally assign a pointer to an object to an
object). Probably the code above should be written as:

Dot temp = Dot(Point( 5, 5));

or more succintly:
Dot temp(Point( 5, 5));

However, with the definition of the Dot-constructer being as it is, this
would not compile. Let's move on:
In Dot class:

//Constructor with default arguments.
Dot::Dot( Point& point= *(new Point( 5, 5 )),
Color& color = *(new Color( 100, 125, 106 )) )

Here you do again use new to create an object. new is a relatively slow
operation (compared to no new), and thus the call is less than optimal in
speed. This is neglectible compared to the memory leak, of course. The
proper constructor should probably be:

Dot::Dot(Point point = Point( 5,5),Color color = Color(100,125,106))

which is better except for a perhaps inefficient passing of arguments. And
this is where const correctness comes into play. If you can, you should
always strive to pass arguments by value (as above) or by const reference
(prefer const reference if you can - except for the simplest types (built
ins)). This gives you the following interface:

Dot::Dot(Point const& point = Point( 5,5),Color const& color =
Color(100,125,106))

In a constructor you should always strive to allow all parameters to be
temporary - which means pass-by value (Point point) or by const reference
(Point const& point).

When you see an assignment x = y; you would not normally expect y to change,
would you? And yet, this is precisely what could happen in your
Dot-constructor.

Kind regards
Peter
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top