473,386 Members | 1,819 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Copy constructor question

Hi guys,

I have a simple question. If I have a class like:

class A {
A();
~A();
A(A& a);
A(int i);

int myvalue;
};

So there's a copy constructor for integers:

A::A(int i) { myvalue = i;}

But if I also want copy constructors for unsigned int, long, float,
double, long double etc, do I have to write them all out? All bodies of
these copy constructors are exactly the same:

A::A(T& t) { myvalue = t;}

Or can templates help me without having to write out all variants?

And what if I have to deal with other classes/types which are not
clearly a 'simple scalar'? For example 'complex'? This needs another
code body because then I need to get the real value (for example):

A::A(complex<double>& c) { myvalue = c.real();}

And of course the complex variable comes in various variants like
double, float, etc...

Thanks for any hints,

Jeroen
Apr 18 '07 #1
19 2353
Jeroen wrote:
Hi guys,

I have a simple question. If I have a class like:

class A {
A();
~A();
A(A& a);
A(int i);

int myvalue;
};

So there's a copy constructor for integers:

A::A(int i) { myvalue = i;}
No, this isn't a copy constructor, there is only one of those (A(A& a),
which should real be A(cont A& a)). It s a constructor.
But if I also want copy constructors for unsigned int, long, float,
double, long double etc, do I have to write them all out?
No, not if there is an automatic conversion from the type to int. If
there is, the int constructor will be used.

--
Ian Collins.
Apr 18 '07 #2
Jeroen wrote:
Hi guys,

I have a simple question. If I have a class like:

class A {
A();
~A();
A(A& a);
A(int i);

int myvalue;
};
The above class is probably defective in that it has a explicit
copy constructor but no copy-assignment operator. If you have
non-standard copy semantics it needs to be done in both places.
>
So there's a copy constructor for integers:

A::A(int i) { myvalue = i;}
The term here is NOT copy-constructor. A copy constructor is
called with a cv-qualified type of the same class. What you
have here is a "coverting constructor" that is a constructor
that can be called with one argument (other than the same class)
and is NOT declared explicit.
>
But if I also want copy constructors for unsigned int, long, float,
double, long double etc, do I have to write them all out?
If all you are going to do is assign to i, why do you think you
need all of these. The single converting constructor from int
would work fine.
A::A(complex<double>& c) { myvalue = c.real();}
Can you say specialization? I knew you could.

typedef <class TA(const complex<T>& c) { myvalue = c.real(); }

You should really make your stuff const correct.
Apr 18 '07 #3
Ian Collins schreef:
Jeroen wrote:
>Hi guys,

I have a simple question. If I have a class like:

class A {
A();
~A();
A(A& a);
A(int i);

int myvalue;
};

So there's a copy constructor for integers:

A::A(int i) { myvalue = i;}
No, this isn't a copy constructor, there is only one of those (A(A& a),
which should real be A(cont A& a)). It s a constructor.
>But if I also want copy constructors for unsigned int, long, float,
double, long double etc, do I have to write them all out?

No, not if there is an automatic conversion from the type to int. If
there is, the int constructor will be used.
OK, thanks for the answer. And you're right (of course), there's only
one copy constructor. Very sloppy of me :-)
Apr 19 '07 #4
Ron Natalie schreef:
Jeroen wrote:
>Hi guys,

I have a simple question. If I have a class like:

class A {
A();
~A();
A(A& a);
A(int i);

int myvalue;
};
The above class is probably defective in that it has a explicit
copy constructor but no copy-assignment operator. If you have
non-standard copy semantics it needs to be done in both places.
Yes, I know. But I tried to leave as much as 'overhead' out (at least
those things that seem not te be important for the question) from the
example.
>>
So there's a copy constructor for integers:

A::A(int i) { myvalue = i;}

The term here is NOT copy-constructor. A copy constructor is
called with a cv-qualified type of the same class. What you
have here is a "coverting constructor" that is a constructor
that can be called with one argument (other than the same class)
and is NOT declared explicit.
Right, very sloppy of me. I knew that...
>
>>
But if I also want copy constructors for unsigned int, long, float,
double, long double etc, do I have to write them all out?

If all you are going to do is assign to i, why do you think you
need all of these. The single converting constructor from int
would work fine.
> A::A(complex<double>& c) { myvalue = c.real();}

Can you say specialization? I knew you could.

typedef <class TA(const complex<T>& c) { myvalue = c.real(); }

You should really make your stuff const correct.
OK, I'll look the 'template specialization' up on the Internet. Thanks
for the example and reply Ron!
Apr 19 '07 #5
Jeroen wrote:
I have a simple question. If I have a class like:

class A {
A();
~A();
A(A& a);
A(int i);

int myvalue;
};
You made several mistakes.
cat A.h
#ifndef A_H
#define A_H
#include <iostream>

class A {
private:
int myvalue;
public:
A(void): myvalue(0) { } // default
A(int i): myvalue(i) { } // explicit
A(A& a): myvalue(a.myvalue) { }// copy
~A(void) { myvalue = 0; } // destructor

friend
std::ostream& operator <<(std::ostream& os, const A& a) {
return os << a.myvalue;
}
};

#endif//A_H
cat main.cc
#include "A.h"

int main (int argc, char* argv[]) {
A a(13);
std::cout << "a = " << a << std::endl;
return 0;
}
g++ -Wall -ansi -O2 -o main main.cc
./main
a = 13

You should test your code before posting it to this newsgroup.
Your constructors and destructor should be public
so that you can use them.
Data should be private.
You need some sort of access function (operator << in this case)
so that you can use the object.

There are implicit conversions to int
so the compiler will use them if you don't provide
explicit constructors for unsigned int etc.

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Apr 19 '07 #6
E. Robert Tisdale wrote:
>
You made several mistakes.
cat A.h
#ifndef A_H
#define A_H
#include <iostream>

class A {
private:
int myvalue;
public:
A(void): myvalue(0) { } // default
This is a C style of declaring/defining functions. C++ does not use void
for empty parameter list.
A(int i): myvalue(i) { } // explicit
A(A& a): myvalue(a.myvalue) { }// copy
Copy constructor is missing const. It should be:
A( const A &a): myvalue( a.myvalue){}
~A(void) { myvalue = 0; } // destructor
Same comment as for the constructor.
BTW why assign 0 to myvalue?
Apr 20 '07 #7
anon wrote:
E. Robert Tisdale wrote:
>>
You made several mistakes.
> cat A.h
#ifndef A_H
#define A_H
#include <iostream>

class A {
private:
int myvalue;
public:
A(void): myvalue(0) { } // default

This is a C style of declaring/defining functions. C++ does not use
void for empty parameter list.
> A(int i): myvalue(i) { } // explicit
A(A& a): myvalue(a.myvalue) { }// copy

Copy constructor is missing const. It should be:
A( const A &a): myvalue( a.myvalue){}
> ~A(void) { myvalue = 0; } // destructor

Same comment as for the constructor.
BTW why assign 0 to myvalue?
In addition to those comments, the two c-tors (the default and the
parameterized on 'int') should be made into one (the new default):

A(int i = 0) : myvalue(i) {}

And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient. The
same for the destructor -- there is no need in it, apparently.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 20 '07 #8
On Apr 20, 3:09 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:

[...]
In addition to those comments, the two c-tors (the default and the
parameterized on 'int') should be made into one (the new default):
A(int i = 0) : myvalue(i) {}
Both solutions are possible. Which one you prefer is a question
of style and taste; there's certainly no "should" about it.
And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient.
Still, most coding guidelines would require an explicit one, to
avoid making it inline.
The
same for the destructor -- there is no need in it, apparently.
Ditto.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 20 '07 #9
James Kanze wrote:
On Apr 20, 3:09 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:

[...]
>In addition to those comments, the two c-tors (the default and the
parameterized on 'int') should be made into one (the new default):
> A(int i = 0) : myvalue(i) {}

Both solutions are possible. Which one you prefer is a question
of style and taste; there's certainly no "should" about it.
Why 'no "should"'? "Should" does not exclude "possible". And I
do not agree that minimizing the number of functions is arbitrary.
It's definitely _better_.
>And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient.

Still, most coding guidelines would require an explicit one, to
avoid making it inline.
How would you "avoid maing it inline" by keeping it in the class
definition?
>The
same for the destructor -- there is no need in it, apparently.

Ditto.
<shrug>

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 20 '07 #10
James Kanze wrote:
Victor Bazarov wrote:
>And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient.

Still, most coding guidelines would require an explicit one, to
avoid making it inline.
Victor is correct of course.
Actually, I would write

//A(const A& a): myvalue(a.myvalue) { }// copy

just to document the fact that I didn't forget the copy constructor.

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Apr 21 '07 #11
E. Robert Tisdale wrote:
James Kanze wrote:
>Victor Bazarov wrote:
>>And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient.


Still, most coding guidelines would require an explicit one, to
avoid making it inline.


Victor is correct of course.
Actually, I would write

//A(const A& a): myvalue(a.myvalue) { }// copy

just to document the fact that I didn't forget the copy constructor.
That's silly, what happens when the class innards change? You have to
maintain the unused constructor.

If anything, write

//A(const A&);// copy

--
Ian Collins.
Apr 21 '07 #12
On Apr 20, 11:36 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
James Kanze wrote:
On Apr 20, 3:09 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
[...]
In addition to those comments, the two c-tors (the default and the
parameterized on 'int') should be made into one (the new default):
A(int i = 0) : myvalue(i) {}
Both solutions are possible. Which one you prefer is a question
of style and taste; there's certainly no "should" about it.
Why 'no "should"'? "Should" does not exclude "possible".
At least in the English I'm most familiar with (that of the
midwest USA), should is a polite form of the imperative. You
*should* adopt the style required by the coding guidelines where
you work. You *can* omit defining the copy constructor in such
cases if the coding guidelines (or other considerations) don't
require it.

As a general rule, in the absense of some specific guideline
otherwise, I will omit it in local classes used only within my
implementation, but provide it explicitly in "published"
classes; those on whose interface other classes, written by
other people, depend. But there are exceptions. In both
directions.
And I do not agree that minimizing the number of functions is
arbitrary. It's definitely _better_.
Except that you don't minimize the number of functions. There
are exactly the same number of functions in both cases.
And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient.
Still, most coding guidelines would require an explicit one, to
avoid making it inline.
How would you "avoid maing it inline" by keeping it in the class
definition?
Every coding guideline I've seen forbids defining functions in
the class definition.

We are talking about professional programming, aren't we?
Obviously, if it's just for your own personal satisfaction, you
do whatever gives you the most satisfaction.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 21 '07 #13
On Apr 21, 3:10 am, Ian Collins <ian-n...@hotmail.comwrote:
E. Robert Tisdale wrote:
James Kanze wrote:
Victor Bazarov wrote:
>And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient.
Still, most coding guidelines would require an explicit one, to
avoid making it inline.
Victor is correct of course.
Actually, I would write
//A(const A& a): myvalue(a.myvalue) { }// copy
just to document the fact that I didn't forget the copy constructor.
That's silly, what happens when the class innards change? You have to
maintain the unused constructor.
If anything, write
//A(const A&);// copy
More usually, I will have a documentation section encompassing
all of the constructors (plus assignment, destruction and swap);
in the rare cases where I use the compiler generated version, I
will mention this there; as a general rule, it's probably worth
mentionning whether copy and assignment are supported as part of
the class documentation, rather than at the individual function
level.

And of course, even if you count on the compiler generated
forms, you still have to document them. So letting the compiler
do the generation doesn't really save much work. (And if your
shop uses Doxygen, or something along those lines, how do you
make the compiler generated defaults show up in the generated
documentation?)

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 21 '07 #14
Ian Collins wrote:
E. Robert Tisdale wrote:
>James Kanze wrote:
>>Victor Bazarov wrote:

And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient.

Still, most coding guidelines would require an explicit one, to
avoid making it inline.

Victor is correct of course.
Actually, I would write

//A(const A& a): myvalue(a.myvalue) { }// copy

just to document the fact that I didn't forget the copy constructor.
That's silly. What happens when the class innards change?
You have to maintain the unused constructor.
Well, the problem with any documentation is that
you must maintain it just like it was code.
If anything, write

//A(const A&);// copy
Which means that you declared but forgot to define the copy constructor?

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Apr 21 '07 #15
In message <11**********************@e65g2000hsc.googlegroups .com>,
James Kanze <ja*********@gmail.comwrites
>On Apr 20, 11:36 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
[... on explicitly writing what the compiler would do anyway]
>
>And I do not agree that minimizing the number of functions is
arbitrary. It's definitely _better_.

Except that you don't minimize the number of functions. There
are exactly the same number of functions in both cases.
But there are more *user-written* functions which have to be maintained
when you add more data members. And the compiler is better at keeping
track of those members - in three different functions - than I am.

--
Richard Herring
Apr 25 '07 #16
In message <f0**********@news.datemas.de>, Victor Bazarov
<v.********@comAcast.netwrites
>anon wrote:
>E. Robert Tisdale wrote:
>>>
You made several mistakes.

cat A.h
#ifndef A_H
#define A_H
#include <iostream>

class A {
private:
int myvalue;
public:
A(void): myvalue(0) { } // default

This is a C style of declaring/defining functions. C++ does not use
void for empty parameter list.
>> A(int i): myvalue(i) { } // explicit
Not explicit without the "explicit" keyword.
>> A(A& a): myvalue(a.myvalue) { }// copy

Copy constructor is missing const. It should be:
A( const A &a): myvalue( a.myvalue){}
>> ~A(void) { myvalue = 0; } // destructor

Same comment as for the constructor.
BTW why assign 0 to myvalue?

In addition to those comments, the two c-tors (the default and the
parameterized on 'int') should be made into one (the new default):

A(int i = 0) : myvalue(i) {}

And there is probably no need for the copy c-tor as it's implemented.
The one the compiler will generate is absolutely sufficient. The
same for the destructor -- there is no need in it, apparently.

V
--
Richard Herring
Apr 25 '07 #17
On Apr 25, 5:14 pm, Richard Herring <ju**@[127.0.0.1]wrote:
In message <1177147807.523762.146...@e65g2000hsc.googlegroups .com>,
James Kanze <james.ka...@gmail.comwrites
On Apr 20, 11:36 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
[... on explicitly writing what the compiler would do anyway]
And I do not agree that minimizing the number of functions is
arbitrary. It's definitely _better_.
Except that you don't minimize the number of functions. There
are exactly the same number of functions in both cases.
But there are more *user-written* functions which have to be maintained
when you add more data members. And the compiler is better at keeping
track of those members - in three different functions - than I am.
Any time you change the data members of the class, you have to
consider those functions, regardless of who wrote them. I don't
see where letting the compiler do it gains anything but less
keystrokes. And you end up with inlined functions, which isn't
necessarily a good idea.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 26 '07 #18
James Kanze wrote:
[..] I don't
see where letting the compiler do it gains anything but less
keystrokes.
Fewer keystrokes means fewer places where the programmer can screw
up. If you don't see any benefit in that, then nothing we can do
about that, unfortunately.
And you end up with inlined functions, which isn't
necessarily a good idea.
Could you elaborate on that, please?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 26 '07 #19
In message <11**********************@u32g2000prd.googlegroups .com>,
James Kanze <ja*********@gmail.comwrites
>On Apr 25, 5:14 pm, Richard Herring <ju**@[127.0.0.1]wrote:
>In message <1177147807.523762.146...@e65g2000hsc.googlegroups .com>,
James Kanze <james.ka...@gmail.comwrites
>On Apr 20, 11:36 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>[... on explicitly writing what the compiler would do anyway]
>And I do not agree that minimizing the number of functions is
arbitrary. It's definitely _better_.
>Except that you don't minimize the number of functions. There
are exactly the same number of functions in both cases.
>But there are more *user-written* functions which have to be maintained
when you add more data members. And the compiler is better at keeping
track of those members - in three different functions - than I am.

Any time you change the data members of the class, you have to
consider those functions, regardless of who wrote them.
Um. Really what you have to consider is (the semantics of) the _data
members_. If my coding standards insist that if a value class has more
than <some small numberdata members, they must all have standard
copy/assign/delete semantics (or be wrapped by something which does),
then I'm assured that the compiler-generated functions will do what's
necessary, and I don't have to look in three additional places to ensure
that all the data members are handled correctly.
I don't
see where letting the compiler do it gains anything but less
keystrokes. And you end up with inlined functions, which isn't
necessarily a good idea.
And it isn't necessarily a bad one.

--
Richard Herring
Apr 26 '07 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Kurt Krueckeberg | last post by:
Given a class X class X { public: X(int); X(const X&); //. . . }; Is this line X x1(1); the same thing as X x2 = 2;
8
by: trying_to_learn | last post by:
Why do we need to explicitly call the copy constructor and the operator = , for base class and member objects in composition? ....book says "You must explicitly call the GameBoard copy-constructor...
8
by: Jesper | last post by:
Hi, Does the concept "copy constructor" from c++ excist in c#. What is the syntax. best regards Jesper.
14
by: Arne | last post by:
In C++ we have a copy constructor. What is the equivalent in .Net? Would that be a clone method?
3
by: subramanian | last post by:
Consider the code fragment: class Test { public: Test(const Test &temp); ... }; ....
22
by: clicwar | last post by:
A simple program with operator overloading and copy constructor: #include <iostream> #include <string> using namespace std; class Vector { private: float x,y; public: Vector(float u, float...
4
by: Rahul | last post by:
Hi Everyone, It is well known that the input parameter which is passed to the copy constructor is passed as reference and not as as object. Because passing an object is as good as making another...
1
by: Visame | last post by:
#include <iostream> using namespace std; class A { public: A() {cout << "constructor A" << endl;} A(A& a) {cout<<"copy A"<<endl;} virtual void Test(){cout <<"A test"...
6
by: suresh | last post by:
Hi Could you please tell why copy constructor is not called in the first line in main(), as mentioned in the text books. I used g++ version 4.1.2 on debian etch thanks suresh # include...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.