473,326 Members | 2,337 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,326 software developers and data experts.

How to avoid the use of copy constructor when using STL container function (push_back, etc.)

The following program calls the normal constructor and the copy
constructor.
By calling the copy constuctor is redundandant, all I want is only a
vector of a trial object.

Is there any way to avoid the use of the copy constructor?

#include <vector>
#include <iostream>

class trial {
public:
trial(int i) {
std::cout << "In constructor" << std::endl;
}
trial(const trial &) {
std::cout << "In copy constructor." << std::endl;
}
};

int main()
{
std::vector<trial> v;
v.push_back(trial(10));
}

/**************output
In constructor.
In copy constructor.
************************/

Apr 1 '06 #1
11 7334
In article <11*********************@t31g2000cwb.googlegroups. com>,
"Pe*******@gmail.com" <Pe*******@gmail.com> wrote:
The following program calls the normal constructor and the copy
constructor.
By calling the copy constuctor is redundandant, all I want is only a
vector of a trial object.

Is there any way to avoid the use of the copy constructor?

#include <vector>
#include <iostream>

class trial {
public:
trial(int i) {
std::cout << "In constructor" << std::endl;
}
trial(const trial &) {
std::cout << "In copy constructor." << std::endl;
} ~trial() {
std::cout << "In destructor." << std::endl;
} };

int main()
{
std::vector<trial> v;
v.push_back(trial(10));
}

/**************output
In constructor.
In copy constructor. In destructor. ************************/


The copy constructor call is not redundant. The vector cannot store the
temporary object you created because it will go out of scope as soon as
the next sequence point is reached. The vector must make a copy of the
trial object to store.
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Apr 1 '06 #2

Pe*******@gmail.com skrev:
The following program calls the normal constructor and the copy
constructor.
By calling the copy constuctor is redundandant, all I want is only a
vector of a trial object.
The copyconstructor is not redundant - it has to be there in order to
copy your object into the vector.
There is a proposal on the way that enables moving object - e.g. during
construction. It would not do anything for your case, however. A move
is typically quite effiecient for small objects.

/Peter
Is there any way to avoid the use of the copy constructor?

#include <vector>
#include <iostream>

class trial {
public:
trial(int i) {
std::cout << "In constructor" << std::endl;
}
trial(const trial &) {
std::cout << "In copy constructor." << std::endl;
}
};

int main()
{
std::vector<trial> v;
v.push_back(trial(10));
}

/**************output
In constructor.
In copy constructor.
************************/


Apr 1 '06 #3
Pe*******@gmail.com wrote:
The following program calls the normal constructor and the copy
constructor.
By calling the copy constuctor is redundandant, all I want is only a
vector of a trial object.

Is there any way to avoid the use of the copy constructor?

#include <vector>
#include <iostream>

class trial {
public:
trial(int i) {
std::cout << "In constructor" << std::endl;
}
trial(const trial &) {
std::cout << "In copy constructor." << std::endl;
}
};

int main()
{
std::vector<trial> v;
v.push_back(trial(10));
}

/**************output
In constructor.
In copy constructor.
************************/

STL containers take elements by value. One suggestion is to use a
container of smart pointers appropriate to your task. Then the copy
is only copying the pointer class. Boost has a number of smart
pointers you can choose from.

BTW, do not use the standard library auto_ptr. Due to it's copy
semantics, it is not appropriate for use in STL containers.

Apr 1 '06 #4
PengYu.UT wrote:
Is there any way to avoid the use of the copy constructor?
Why avoid it? Have you proven that this one little copy makes your program
slow? If your program is fast, stay with simple techniques that make your
program easy to debug and grow.
std::vector<trial> v;


If you switch to <trial*>, then you will need to call delete on each item in
the vector. But pointer copies will be very efficient.

Generally, std::auto_ptr<trial> could safely delete a pointer, but you
should not store auto_ptr inside any STL container (or most other
containers).

The next step is a shared smart pointer, such as boost::shared_ptr. Only
invest in a vector<boost::shared_ptr<trial> > after you prove you need it.
Copying a small object may be faster than copying a shared pointer.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 1 '06 #5
An**********@gmail.com wrote:
BTW, do not use the standard library auto_ptr. Due to it's copy
semantics, it is not appropriate for use in STL containers.


Any fully compliant C++ compiler will not allow you to do a push_back
to a container of std::vector<auto_ptr<T> > type.
---------------------------------------------------------------------------*-------------

David Maisonave
http://axter.com

Author of policy smart pointers (http://axter.com/smartptr)
Top ten member of C++ Expert Exchange:
http://www.experts-exchange.com/Cplusplus
---------------------------------------------------------------------------*-------------

Apr 2 '06 #6
Pe*******@gmail.com wrote:
The following program calls the normal constructor and the copy
constructor.
By calling the copy constuctor is redundandant, all I want is only a
vector of a trial object.

Is there any way to avoid the use of the copy constructor?


You can use a clone smart pointer like the following:
http://code.axter.com/copy_ptr.h

---------------------------------------------------------------------------*-------------

David Maisonave
http://axter.com

Author of policy smart pointers (http://axter.com/smartptr)
Top ten member of C++ Expert Exchange:
http://www.experts-exchange.com/Cplusplus
---------------------------------------------------------------------------*-------------

Apr 2 '06 #7
Axter wrote:
An**********@gmail.com wrote:
BTW, do not use the standard library auto_ptr. Due to it's copy
semantics, it is not appropriate for use in STL containers.


Any fully compliant C++ compiler will not allow you to do a push_back
to a container of std::vector<auto_ptr<T> > type.


Where in the standard did you find that? The closest I found is [20.4.5/3]:

[...] auto_ptr does not meet the CopyConstructible and Assignable
requirements for Standard Library container elements and thus
instantiating a Standard Library container with an auto_ptr results
in undefined behavior.

This quote says it's undefined behavior. You seem to claim that it is an
error and diagnostics is required.
Best

Kai-Uwe Bux
Apr 2 '06 #8
Kai-Uwe Bux wrote:
Any fully compliant C++ compiler will not allow you to do a push_back
to a container of std::vector<auto_ptr<T> > type.


Where in the standard did you find that? The closest I found is
[20.4.5/3]:

[...] auto_ptr does not meet the CopyConstructible and Assignable
requirements for Standard Library container elements and thus
instantiating a Standard Library container with an auto_ptr results
in undefined behavior.

This quote says it's undefined behavior. You seem to claim that it is an
error and diagnostics is required.


If the Standard doesn't define "not allow", then your quote indeed sets the
bounds where programmers should not allow themselves to go.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 2 '06 #9

"Kai-Uwe Bux" <jk********@gmx.net> skrev i meddelandet
news:e0**********@murdoch.acc.Virginia.EDU...
Axter wrote:
An**********@gmail.com wrote:
BTW, do not use the standard library auto_ptr. Due to it's copy
semantics, it is not appropriate for use in STL containers.


Any fully compliant C++ compiler will not allow you to do a
push_back
to a container of std::vector<auto_ptr<T> > type.


Where in the standard did you find that? The closest I found is
[20.4.5/3]:

[...] auto_ptr does not meet the CopyConstructible and Assignable
requirements for Standard Library container elements and thus
instantiating a Standard Library container with an auto_ptr results
in undefined behavior.

This quote says it's undefined behavior. You seem to claim that it
is an
error and diagnostics is required.


One possible outcome of undefined behavior is a diagnostic.

Class auto_ptr is defined in such a way that a diagnosable error is
*highly likely* to occur, if you use it in a standard container. It is
not strictly required though.
Bo Persson
Apr 2 '06 #10
Kai-Uwe Bux wrote:
Axter wrote:
An**********@gmail.com wrote:
BTW, do not use the standard library auto_ptr. Due to it's copy
semantics, it is not appropriate for use in STL containers.


Any fully compliant C++ compiler will not allow you to do a push_back
to a container of std::vector<auto_ptr<T> > type.


Where in the standard did you find that? The closest I found is [20.4.5/3]:

[...] auto_ptr does not meet the CopyConstructible and Assignable
requirements for Standard Library container elements and thus
instantiating a Standard Library container with an auto_ptr results
in undefined behavior.

This quote says it's undefined behavior. You seem to claim that it is an
error and diagnostics is required.


IAW the standard it is considered undefined behavior to instantiate
this type, but that's not what I'm referring to, and that's why I
specified push_back call for auto_ptr type.

std::vector<auto_ptr<T> > ptr; //This is undefined IAW C++ standard

ptr.push_back(auto_ptr<T>(new T)); //This is not allowed IAW C++
standard
IAW the standard, you can NOT perform a push_back of an auto_ptr<T> to
a container of auto_ptr<T>.
The standard doesn't explicitly state this, and it would be hard for it
to do so on a type that is undefined.
But it does disallow it indirectly, since the standard clearly defines
an auto_ptr copy constructor taking a non-constant type, and a
vector::push_back taking a constant type.
20.4.5.1 auto_ptr constructors
auto_ptr(auto_ptr &a) throw();

//23.2.4.3 modifiers
void push_back(const T& x);

So IAW C++ standard you can not perform a push_back of type auto_ptr<T>
on a container of auto_ptr<T>.

IAW C++ standard, your compiler may or may not let you declare a
container of auto_ptr<T>, but it can not let you populate it via
push_back.
----------------------------------------------------------------------------------------
David Maisonave
http://axter.com
----------------------------------------------------------------------------------------

Apr 3 '06 #11
Axter wrote:
Kai-Uwe Bux wrote:
Axter wrote:
> An**********@gmail.com wrote:
>> BTW, do not use the standard library auto_ptr. Due to it's copy
>> semantics, it is not appropriate for use in STL containers.
>
> Any fully compliant C++ compiler will not allow you to do a push_back
> to a container of std::vector<auto_ptr<T> > type.
Where in the standard did you find that? The closest I found is
[20.4.5/3]:

[...] auto_ptr does not meet the CopyConstructible and Assignable
requirements for Standard Library container elements and thus
instantiating a Standard Library container with an auto_ptr results
in undefined behavior.

This quote says it's undefined behavior. You seem to claim that it is an
error and diagnostics is required.

[snip] But it does disallow it indirectly, since the standard clearly defines
an auto_ptr copy constructor taking a non-constant type, and a
vector::push_back taking a constant type.
20.4.5.1 auto_ptr constructors
auto_ptr(auto_ptr &a) throw();

//23.2.4.3 modifiers
void push_back(const T& x);

So IAW C++ standard you can not perform a push_back of type auto_ptr<T>
on a container of auto_ptr<T>.

IAW C++ standard, your compiler may or may not let you declare a
container of auto_ptr<T>, but it can not let you populate it via
push_back.


Hm, I think you are reading too much into the signatures. Consider the
following (absolutely unlikely and bad) implementation of std::vector:
#include <cstddef>
#include <memory>
#include <cassert>

namespace std {

template < typename T, typename A = std::allocator<T> >
struct vector {

typedef std::size_t size_type;
typedef T value_type;
typedef T * pointer;
typedef T const * const_pointer;
typedef T & reference;
typedef T const & const_reference;

private:

pointer the_data;
size_type the_size;
size_type the_cap;

public:

// ...

void push_back ( const_reference c_ref ) {
if ( the_size == the_cap ) {
// do some fancy reallocation stuff
}
assert( the_size < the_cap );
new ( the_data + the_size )
value_type ( const_cast<reference>( c_ref ) );
++ the_size;
}

}; // vector

} // namespace std
I would claim that this implementation is conforming:

a) it has the right signature.
b) for any type T that satisfies the conceptual requirements (like
CopyConstructible), it does the right thing.

This implementation will, however, not trigger an error message for
std::auto_ptr.
As a practical matter, of course, you are right: it is more than likely that
a compiler will give you an error. But I do not see why it would be
required to do so by the standard.

Best

Kai-Uwe Bux
Apr 3 '06 #12

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

Similar topics

26
by: Peter Olcott | last post by:
// // Is there something wrong with my syntax for the // Copy Constructor of an Array Element, or does // the C++ language not support this? // #include <stdio.h> #include <stdlib.h> ...
9
by: Gunnar G | last post by:
Is there anything like vector in STL, that performes deep copy of the elements it contains? I hope this will appear in future releases of STL :)
8
by: Markus Dehmann | last post by:
I defined a base class in order to put heterogeneous values into a standard container: All values that I store in the container are derived from my base class. Now when I iterate over the...
14
by: Jinjun Xu | last post by:
Hi, I have an array and I want to adjust the size (remove some elements). I use the following code. Can you help me to check whether it's correct. ////////////// start int *p1 = new int; ...
8
by: RonHiler | last post by:
My copy constructor is crashing my program, and I can't figure out why. I'll try to make the code listing as short as I can. Here are the two headers: class BreakthroughClass { public:...
7
by: vj | last post by:
Hi! I recently came across this intresting behaviour shown by Visual C++ 6.0 compiler regarding Copy Constructors. Please tell me that is this the standard behaviour shown by all compilers or its...
18
by: sd2004 | last post by:
could someone please show/help me to copy all element from "class dog" to "class new_dog" ? Note: "class new_dog" has new element "age" which should have value "my_age"...
17
by: qazmlp1209 | last post by:
Will the following program cause any problem, because of the missing explicit copy constructor for the 'test' class? #include <vector> #include <iostream> class test { char* cPtr ;
6
by: Peng Yu | last post by:
Hi, I'm wondering if the following assignment is lazy copy or not? Thanks, Peng std::vector<intv. v.push_back(1); v.push_back(2);
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.