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

ctor, operator =

Hello,

i defined an overloaded operator = for my class which works perfect
outside of my class.

In this case, is following ctor valid?

test::test (const test& src){
*this=src;
}

Thanks and regards
marbac
Jul 23 '05 #1
14 1477
marbac wrote:
...
i defined an overloaded operator = for my class which works perfect
outside of my class.

In this case, is following ctor valid?

test::test (const test& src){
*this=src;
}
...


In general case - no. Assignment operator is normally applied to the
already constructed object and in general case the implementation of the
assignment operator will rely on that fact. In the code above you are
trying to apply the assignment operator to an object, which has not been
constructed yet. Whether this is a problem in your particular case
depends on your class implementation details.

--
Best regards,
Andrey Tarasevich

Jul 23 '05 #2
Andrey Tarasevich schrieb:
In general case - no. Assignment operator is normally applied to the
already constructed object and in general case the implementation of the
assignment operator will rely on that fact. In the code above you are
trying to apply the assignment operator to an object, which has not been
constructed yet. Whether this is a problem in your particular case
depends on your class implementation details.


Well i reduced my code to a simple example to show my problem.
And I also found the mistake i made ... what a mess, because
it has nothing to do with the question "
copy constructor with operator = is valid?"

thanks a lot and regards marbac

#include <iostream>

class test {

public:
test (int _size): size(_size) {
if (size>0) array=new int [this->size];
else array=0;

}

test (test& src) {
array=0; // THIS WAS MISSING!!
*this=src;
}

~test () {
if (array) delete [] array;
}

test& operator = (const test& src) {
size=src.size;
if (array) delete [] array;
if (size>0) array=new int [this->size];
else array=0;
return *this;
}

void cout_size () {
std::cout << "Size:" << size << std::endl;
}

private:
int *array;
int size;
};
int main () {
test a(4);
test b(5);
test c(6);

a.cout_size();
b.cout_size();
c.cout_size();

a=b;
a.cout_size();

test d (a); //runtime - error if deleting non 0 pointer at construction
time
d.cout_size ();
}
Jul 23 '05 #3
marbac wrote:
[snip]
#include <iostream>

class test {

public: [snip] test& operator = (const test& src) {
size=src.size;
if (array) delete [] array;
if (size>0) array=new int [this->size];
else array=0;
return *this;
}

You should wrap the body of your operator = () in any class like this:
test& operator = (const test& src) {
if(this != &src) {
size=src.size;
if (array) delete [] array;
if (size>0) array=new int [this->size];
else array=0;
}

return *this;
}

Even though above you aren't copying data, just allocating space, I'm gonna
assume you plan to copy data eventually. In which case, the original values in
a.array would have been lost.
Jul 23 '05 #4
marbac wrote:
...
In general case - no. Assignment operator is normally applied to the
already constructed object and in general case the implementation of the
assignment operator will rely on that fact. In the code above you are
trying to apply the assignment operator to an object, which has not been
constructed yet. Whether this is a problem in your particular case
depends on your class implementation details.


Well i reduced my code to a simple example to show my problem.
And I also found the mistake i made ... what a mess, because
it has nothing to do with the question "
copy constructor with operator = is valid?"


Well, actually it has everything to do with that question. The problem
you had in your code is exactly what I was talking about. You called
assignment operator for an object, which was not constructed yet (it
contained garbage in 'array' field).

--
Best regards,
Andrey Tarasevich

Jul 23 '05 #5
marbac wrote:
Andrey Tarasevich schrieb:
In general case - no. Assignment operator is normally applied to the
already constructed object and in general case the implementation of the
assignment operator will rely on that fact. In the code above you are
trying to apply the assignment operator to an object, which has not been
constructed yet. Whether this is a problem in your particular case
depends on your class implementation details.

Well i reduced my code to a simple example to show my problem.
And I also found the mistake i made ... what a mess, because
it has nothing to do with the question "
copy constructor with operator = is valid?"

thanks a lot and regards marbac

#include <iostream>

class test {

public:
test (int _size): size(_size) {
if (size>0) array=new int [this->size];
else array=0;

}

test (test& src) {
array=0; // THIS WAS MISSING!!
*this=src;
}

~test () {
if (array) delete [] array;
}

test& operator = (const test& src) {
size=src.size;
if (array) delete [] array;
if (size>0) array=new int [this->size];
else array=0;
return *this;
}

void cout_size () {
std::cout << "Size:" << size << std::endl;
}

private:
int *array;
int size;
};

How about:

class test {
std::vector<int> array;
public:
test(int size) : array(size) { }
void cout_size() { std::cout << "Size: " << array.size() << "\n"; }
};

Let vector do the work. No extra effort for destruction or copying.
Jul 23 '05 #6
Ron Natalie schrieb:
Let vector do the work. No extra effort for destruction or copying.


I thought about using a vector. But i can imagine, that vector
adds a large amount of overhead to the problem.

In my example unacceptable overhead because I am writing a programm
which accesses large scalarfields to make calculations based on the
scalarfield (e.g. make a directional derivative).
Jul 23 '05 #7
marbac wrote:

Ron Natalie schrieb:
Let vector do the work. No extra effort for destruction or copying.
I thought about using a vector. But i can imagine, that vector
adds a large amount of overhead to the problem.


Have you tried it?
On nearly all std::vector implementations, it is the case that
you don't pay *any* runtime overhead. It may be that std::vector
allocates more memory then absolutely needed. But usually it
is not a problem to program in a way such that this doesn't
happen (or use a std::valarray)

In my example unacceptable overhead because I am writing a programm
which accesses large scalarfields to make calculations based on the
scalarfield (e.g. make a directional derivative).


As said: std::vector usually behaves very much the same then anything
you can come up with by yourself with respect to runtime. Sometimes
it happens that std::vector outperforms a homemade implementation.
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #8
Karl Heinz Buchegger schrieb:
marbac wrote:
Ron Natalie schrieb:

Let vector do the work. No extra effort for destruction or copying.


I thought about using a vector. But i can imagine, that vector
adds a large amount of overhead to the problem.

Have you tried it?


Good Question.Yes, I have. The Results are, that accessing
int-elements on vector takes more than twice the time in comparison with
accessing int-elements of an array (just write/read) using gcc.
I didn`t use valarray yet ... would be interesting to know how it behaves.

Jul 23 '05 #9
marbac wrote:

Karl Heinz Buchegger schrieb:
marbac wrote:
Ron Natalie schrieb:
Let vector do the work. No extra effort for destruction or copying.

I thought about using a vector. But i can imagine, that vector
adds a large amount of overhead to the problem.

Have you tried it?


Good Question.Yes, I have. The Results are, that accessing
int-elements on vector takes more than twice the time in comparison with
accessing int-elements of an array (just write/read) using gcc.


Did you test a debug or a release build?
It is not uncommon, that debug builds execute slower. But all
of this turns around, once the compiler is allowed to do some
optimizations.
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #10
marbac wrote:
Karl Heinz Buchegger schrieb:

Did you test a debug or a release build?
It is not uncommon, that debug builds execute slower. But all
of this turns around, once the compiler is allowed to do some
optimizations.

Hi,

g++ -O3 ...
gives me the same time for both tests.

Thanks
marbac


The specific issue is that the debug mode disables inlining.
That's what usually kills the C++ library performance as the
operator[] plus lots of other tiny functions that should be
inlined don't get done.
Jul 23 '05 #11
marbac wrote:

Karl Heinz Buchegger schrieb:

Did you test a debug or a release build?
It is not uncommon, that debug builds execute slower. But all
of this turns around, once the compiler is allowed to do some
optimizations.

Hi,

g++ -O3 ...
gives me the same time for both tests.


Could you post your test program.
Your timeing is quite unusual.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #12
Karl Heinz Buchegger schrieb:

Could you post your test program.
Your timeing is quite unusual.


Sure, but it seems, that i have to get deeper into vectors than i
wanted, because i played a little bit with the 2 #defines ...

#include <ctime>
#include <vector>
#include <iostream>

#define SAMPLES 100000000
#define SIZE 50

using namespace std;

int main () {

int *intptr;
int tmpint;
vector <int> intvector;
time_t start,stop;

time(&start);
for (int tmp=0; tmp<SAMPLES; tmp++){
intptr=new int[SIZE];
for (int tmp2=0; tmp2<SIZE;tmp2++) intptr[tmp2]=tmp2;
for (int tmp2=0; tmp2<SIZE;tmp2++) tmpint=intptr[tmp2];
delete [] intptr;
}

time(&stop);

cout << "Test1: " << difftime(stop,start) << " s" << endl;

time(&start);
for (int tmp=0; tmp<SAMPLES; tmp++){
for (int tmp2=0; tmp2<SIZE;tmp2++) intvector.push_back(tmp2);
for (int tmp2=0; tmp2<SIZE;tmp2++) tmpint=intvector[tmp2];
intvector.clear();
}
time(&stop);

cout << "Test2: " << difftime(stop,start) << " s" << endl;
}
Jul 23 '05 #13
marbac wrote:

Karl Heinz Buchegger schrieb:

Could you post your test program.
Your timeing is quite unusual.


Sure, but it seems, that i have to get deeper into vectors than i
wanted, because i played a little bit with the 2 #defines ...


Hmm. You are not comparing the time values for vector
and plain int arrays.

Well. Your benchmark is not fair.
For one, you allocate the int array in one big rush, while
you depend on the vector to enlarge itself whenever needed.
That's 2 completely different operations, since the vector
has to do additional operations to ensure that you don't
overflow it. If you need to add that functionality to your
own dynamically allocated array, it would slow down also.

But it can be cured easily. Just tell the vector
how many integers it should expect

time(&start);
for ( tmp=0; tmp<SAMPLES; tmp++){
vector <int> intvector( SIZE );
for (int tmp2=0; tmp2<SIZE;tmp2++) intvector[tmp2]=tmp2;
for ( tmp2=0; tmp2<SIZE;tmp2++) tmpint=intvector[tmp2];
}
time(&stop);

With this modification, the allocated array and the vector are on a near
tie on my system.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #14
Karl Heinz Buchegger wrote:
But it can be cured easily. Just tell the vector
how many integers it should expect

time(&start);
for ( tmp=0; tmp<SAMPLES; tmp++){
vector <int> intvector( SIZE );
for (int tmp2=0; tmp2<SIZE;tmp2++) intvector[tmp2]=tmp2;
for ( tmp2=0; tmp2<SIZE;tmp2++) tmpint=intvector[tmp2];
}
time(&stop);

With this modification, the allocated array and the vector are on a near
tie on my system.


Hi,

i investigated a little bit more time into this issue after your last
posting, because i also need a method to measure the efficiency of
sorting-algorithms

I had to rewrite your method a little bit for this test (vector resize).
I also took the architekturespecific rdtsc as timing reference, after i
was looking for a more precice method to catch the time. It might be not
standard conform from now on ... maybe [OT][OT]

Open issues: Huge Peaks -> out of process time-slice?

Regards marbac

#include <iostream>
#include <asm/msr.h> //not part of the standard ... found nothing
#include <vector>

using namespace std;

unsigned long int cyclecount() { //own time not eliminated
union {
unsigned int a[2];
unsigned long int b;
} tmp;
rdtsc(tmp.a[0],tmp.a[1]);
return tmp.b;
}

int main () {

int *intptr;
int tmpint;
vector <int> intvector;
unsigned long int start,stop;
for (int SIZE=1; SIZE<5000000; SIZE+=100000) {

start=cyclecount();
intptr=new int[SIZE];
for (int tmp2=0; tmp2<SIZE;tmp2++) intptr[tmp2]=tmp2;
for (int tmp2=0; tmp2<SIZE;tmp2++) tmpint=intptr[tmp2];
delete [] intptr;
stop=cyclecount();

cout << SIZE<<";" << stop-start << ";";

start=cyclecount();
for (int tmp2=0; tmp2<SIZE;tmp2++)
intvector.push_back(tmp2);
for (int tmp2=0; tmp2<SIZE;tmp2++)
tmpint=intvector[tmp2];
intvector.clear();
stop=cyclecount();

cout << stop-start << ";" ;

start=cyclecount();
intvector.resize( SIZE );
for (int tmp2=0; tmp2<SIZE;tmp2++) intvector[tmp2]=tmp2;
for (int tmp2=0; tmp2<SIZE;tmp2++)
tmpint=intvector[tmp2];
intvector.clear();
stop=cyclecount();

cout << stop-start << endl;
}
}
Results in CSV:

SIZE;PTRARRAY;VECPUSH;VEC[]
1;90240;33813;2654
100001;1896656;5664987;3146048
200001;4230510;9652769;6954714
300001;6560475;19215142;10414353
400001;8369995;8882148;15616197
500001;10558827;11020351;17199550
600001;12684491;37278433;20708852
700001;15086101;16791983;24092673
800001;17071504;19370898;28661935
900001;21307146;20523950;31445133
1000001;23156010;20607862;34606138
1100001;25174683;73625877;59363345
1200001;69786689;24653751;44094400
1300001;29101467;26656635;44958542
1400001;31332855;28733868;48584683
1500001;33332168;30702743;52032413
1600001;35405227;32930185;55892739
1700001;37700109;34945367;58622792
1800001;39462811;36891294;62915030
1900001;41600231;38950686;65648007
2000001;43695271;42831192;69223034
2100001;49232075;128685758;72172464
2200001;50027132;44577776;75539856
2300001;52210913;47116775;79139642
2400001;54281571;48872439;82872617
2500001;57062003;50617815;85639494
2600001;58712443;52762684;89109782
2700001;60791390;54667671;92389609
2800001;62956952;56679381;96426701
2900001;64791646;58617808;100038896
3000001;66694691;60873717;104918710
3100001;69668862;63589150;105669219
3200001;71590029;64368308;108763045
3300001;73443406;66443554;114306131
3400001;75971787;68211420;115523403
3500001;77243384;70734080;119151197
3600001;79104939;73109602;122264614
3700001;82405595;74260025;127104789
3800001;82316763;76214869;131076252
3900001;83774542;79485742;133650033
4000001;87420350;80137556;135647762
4100001;89002910;82514142;139303053
4200001;92127870;255667184;143994369
4300001;93281569;87342295;147955058
4400001;95212196;90756951;150916301
4500001;102373012;92316403;154436919
4600001;99994411;93167989;157996168
4700001;104611956;96599927;160801089
4800001;104253083;97598571;164166263
4900001;108748142;99228504;168168065

Jul 23 '05 #15

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

Similar topics

9
by: Martin Häcker | last post by:
Hi there, I just tried to run this code and failed miserably - though I dunno why. Could any of you please enlighten me why this doesn't work? Thanks a bunch. --- snip --- import unittest...
4
by: Apricot | last post by:
#include <iostream> #include <string> #include <map> using namespace std ; class tst { public : tst() { cout << "tst::constructor" << endl ; } tst(const tst & that) { cout << "tst::copy...
1
by: Tony Johansson | last post by:
This class template and main works perfectly fine. But could be better. I have this class template called Handle that has a pointer declared as T* body; As you can see I have a reference counter...
4
by: ksukhonosenko | last post by:
This message was originally posted to comp.lang.c++.moderated ---------------------------------------------------------------------------------------------- Hi! I face a problem in my...
8
by: Grizlyk | last post by:
Good morning. Look here: http://groups.google.com/group/fido7.ru.cpp.chainik/browse_frm/thread/7341aba5238c0f79 and here:...
2
by: subramanian | last post by:
Consider the following program: #include <iostream> #include <string> class Member { int x; int y; public: Member(int argx, int argy);
5
by: Diwa | last post by:
Does the "value" type (value as in key-value pair )of "std::map" require a default ctor even if it is not used ? If I comment out Line 1 in the code attached later, i.e remove the default ctor...
15
by: subramanian100in | last post by:
consider the following program: #include <iostream> using namespace std; class Test { public: Test(int xx) : x(xx) { cout << x << endl; }
9
by: puzzlecracker | last post by:
From my understanding, if you declare any sort of constructors, (excluding copy ctor), the default will not be included by default. Is this correct? class Foo{ public: Foo(int); // no...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.