473,883 Members | 1,886 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Copy Constructor and other questions

MSR
I have a couple of questions.

1. Copy Constructor.

class A {
private:
int a1;
double d1;
char *ptr;

public:
const A* operator=(const A* b)
{
memcpy(this, b, sizeof(A));
ptr = new char[100];
};

};

int main()
{
A *b = new b;
A *c=b;
.............
..........
};

Does C++ guarantee that my memcpy always make an exact duplicate of Object
'b' no matter how big the class is. Is this a general way of writing copy
constructors?
2. Null Reference. For example we have a function that searches a list and
returns a pointer to an object if it is found or NULL if it can't find the
object. How can I do this if I want to return a reference instead of a
pointer, without throwing exceptions?
3. This code is from FAQ lite.

class Point {
public:
static Point rectangular(flo at x, float y); // Rectangular coord's
static Point polar(float radius, float angle); // Polar coordinates
// These static methods are the so-called "named constructors"
...
private:
Point(float x, float y); // Rectangular coordinates
float x_, y_;
};

inline Point::Point(fl oat x, float y)
: x_(x), y_(y) { }

inline Point Point::rectangu lar(float x, float y)
{ return Point(x, y); }

inline Point Point::polar(fl oat radius, float angle)
{ return Point(radius*co s(angle), radius*sin(angl e)); }

int main()
{
Point p1 = Point::rectangu lar(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5. 7, 1.2); // Obviously polar
...
}

Dumb question. Now who owns p1 and p2 and how can I delete them?

Thanks for your time and help
--MSR
Jul 23 '05 #1
14 1993
"MSR" <ms********@com cast.net> wrote...
I have a couple of questions.

1. Copy Constructor.

class A {
private:
Everything is private by default in a class. No need to clutter your
code with unnecessary constructs.
int a1;
double d1;
char *ptr;

public:
const A* operator=(const A* b)
{
memcpy(this, b, sizeof(A));
ptr = new char[100];
}; ^
This semicolon is superfluous.

};

int main()
{
A *b = new b;
A *c=b;
It would be so much easier if you just declared those as objects and
didn't busy yourself with 'new' or 'delete' for at least a while.
............
.........
};

Does C++ guarantee that my memcpy always make an exact duplicate of Object
'b' no matter how big the class is.
C++ guarantees NOTHING when it comes to C library functions. That's C's
job to guarantee those. And since C knows NOTHING about classes, the use
of memcpy with non-POD types is _undefined_.
Is this a general way of writing copy constructors?
Of course not. First of all what you wrote is an assignment operator
and not a copy constructor. Second, using memcpy with classes (as I
already mentioned) is undefined. Third, it is extremely dangerous even
if it were defined. Trust me, you don't want go around copying class
objects using memcpy. Just use copy construction semantics for all your
data. If it's a dynamic array, copy it by allocating and then by using
std::copy on it.

Also, class A as you wrote (a) does not copy the array pointed to by
the member 'ptr' (and instead just allocates it and leaves it alone)
and (b) lacks any other construction. Perhaps you didn't want to write
other [irrelevant] things, but when dynamic memory management is used,
the "rule of three" has to be followed (or else).
2. Null Reference.
No such thing exists.
For example we have a function that searches a list and returns a pointer
to an object if it is found or NULL if it can't find the object. How can I
do this if I want to return a reference instead of a pointer, without
throwing exceptions?
You can't.
3. This code is from FAQ lite.

class Point {
public:
static Point rectangular(flo at x, float y); // Rectangular coord's
static Point polar(float radius, float angle); // Polar coordinates
// These static methods are the so-called "named constructors"
...
private:
Point(float x, float y); // Rectangular coordinates
float x_, y_;
};

inline Point::Point(fl oat x, float y)
: x_(x), y_(y) { }

inline Point Point::rectangu lar(float x, float y)
{ return Point(x, y); }

inline Point Point::polar(fl oat radius, float angle)
{ return Point(radius*co s(angle), radius*sin(angl e)); }

int main()
{
Point p1 = Point::rectangu lar(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5. 7, 1.2); // Obviously polar
...
}

Dumb question. Now who owns p1 and p2 and how can I delete them?


They are automatic variables and will be disposed of at the end of
the 'main' function body. Nobody "owns" them and they don't need to
be explicitly deleted. Only objects created by 'new' need to be
'delete'd.

What book are you reading that doesn't talk about copy construction
and automatic variables?

V
Jul 23 '05 #2
MSR wrote:
class A {
private:
int a1;
double d1;
char *ptr;

public:
const A* operator=(const A* b)
{
memcpy(this, b, sizeof(A));
ptr = new char[100];
};

};

Does C++ guarantee that my memcpy always make an exact duplicate of Object
'b' no matter how big the class is. Is this a general way of writing copy
constructors?
Yes, memcpy makes an exact copy of the memory pointed to but...

NO, NO, NOOOOOOO This is not the general way of writing copy
constructors!!! Besides, what you coded is the assignment operator.
Well, sort of. Usually they deal with const references to the source
object, not pointers.

Consider these problems:

A alpha;
alpha = &alpha; // hint, think memory leak

Consider passing a pointer to a class derived from A??? IIRC 'this'
points to *all* the storage for the object, and I believe in most
implementations the first thing there is the vtbl pointer. So your
blind memcpy will step on the A's vtbl pointer and point it at the
derived class's vtbl. Madness surely lies down this path... I know I
know, your example doesn't have virtual methods but I'm being general
here. And in general, memcpy is a bad idea in C++.

A more usual copy constructor for A would look something like:

A( const A& src ) : a1(src.a1), d1(src.d1), ptr(NULL)
{
if(src.ptr != NULL)
{
ptr = new char[ std::strlen(src .ptr) + 1 ];
std::strcpy(ptr ,src.ptr);
}
}

And an assignment operator would look like:

A& operator=( const A& src )
{
if( &src != this ) // check for self-assignment
{
a1 = src.a1;
d1 = src.d1;
delete[] ptr;
if( src.ptr == NULL )
ptr = NULL;
else
{
ptr = new char[ std::strlen(src .ptr) + 1 ];
std::strcpy(ptr ,src.ptr);
}
}
return *this;
}

2. Null Reference. For example we have a function that searches a list and
returns a pointer to an object if it is found or NULL if it can't find the
object. How can I do this if I want to return a reference instead of a
pointer, without throwing exceptions?
Well, you can return a reference to NULL, but then the burden is on the
code making the call to remember to check and see if the & of the
reffered-to object is NULL. (blech)

Bite the bullet, throw exceptions.

Don't return references.

Create a default and plug it in, return that reference.

Have a static "blank" or default no-value-found object and return a
reference to it.
3. This code is from FAQ lite.

class Point {
public:
static Point rectangular(flo at x, float y); // Rectangular coord's
static Point polar(float radius, float angle); // Polar coordinates
// These static methods are the so-called "named constructors"
...
private:
Point(float x, float y); // Rectangular coordinates
float x_, y_;
};

inline Point::Point(fl oat x, float y)
: x_(x), y_(y) { }

inline Point Point::rectangu lar(float x, float y)
{ return Point(x, y); }

inline Point Point::polar(fl oat radius, float angle)
{ return Point(radius*co s(angle), radius*sin(angl e)); }

int main()
{
Point p1 = Point::rectangu lar(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5. 7, 1.2); // Obviously polar
...
}

Dumb question. Now who owns p1 and p2 and how can I delete them?


The local scope within the main() function owns the objects. Short
answer - you don't delete them. The compiler generates code that
deletes them (off the stack, not the heap!) when the function
exits/returns. (or throws an exception)

Jul 23 '05 #3
Sep
1. That is not a copy constructor. A copy constructor is named the
same as the class, has an implicit (that must be implicit) return type
of void and gets a similar value to
class_name const &ob
as its only parameter.

What you have implemented is a copy-assignment operator which is what
is called when the class participates as an lvalue after it has been
constructed. To illustrate this
class_name cl = c; //Would call the copy constructor
cl = c; //Would call the copy-assignment operator
To clarify a bit more, copy constructors usually do not involve
memcpying the other ob to the this pointer (neither does the
copy-assignment operator for that matter). Normally, any
non-pointermembers are copied by value using normal assignment
statements and any pointer members are assigned new storage and the
contents of the other object's pointer copied over.

Also, just so you know, the test code, as you've implemented it, will
do a standard assignment between the two pointers when assigning one to
the other as the copy-assignment operator that you did implement takes
as its implicit first parameter an object of type A and not type A*.
2. If you're returning a pointer to an object if it is found, then why
would you declaring the function as reference and not pointer? I don't
quite understand what you're trying to accomplish with it.
3. p1 and p2 are both local variables owned by the main function and
are automatically deleted as they were allocated on the stack, that is,
they needn't be deleted through any special syntax.

Jul 23 '05 #4
"Phil Staite" <ph**@nospam.co m> wrote...
MSR wrote:
[...]
2. Null Reference. For example we have a function that searches a list
and returns a pointer to an object if it is found or NULL if it can't
find the object. How can I do this if I want to return a reference
instead of a pointer, without throwing exceptions?


Well, you can return a reference to NULL, [..]


How?
Jul 23 '05 #5
Sep
Do note, MSR, that the test code for your first question would not even
invoke that copy assignment operator if it were attempting assignation
and not copy construction. You overloaded operator = for objects of
type A only and not A*, thus the assignation taking place is a standard
scalar object to scalar object assignation resulting in the second
pointer pointing to the same block of memory that the first is.

Jul 23 '05 #6
MSR

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:lo******** ************@co mcast.com...
"MSR" <ms********@com cast.net> wrote...
I have a couple of questions.

1. Copy Constructor.

class A {
private:
Everything is private by default in a class. No need to clutter your
code with unnecessary constructs.
int a1;
double d1;
char *ptr;

public:
const A* operator=(const A* b)
{
memcpy(this, b, sizeof(A));
ptr = new char[100];
};

^
This semicolon is superfluous.

};

int main()
{
A *b = new b;
A *c=b;


It would be so much easier if you just declared those as objects and
didn't busy yourself with 'new' or 'delete' for at least a while.


I wrote this simple class purely for posting. So was lazy to really
implement
something that resembles my real problem. In my real problem I do need
pointers as I need to do dynamic allocation. So, I tried to put my problem
in simplest way , but it probably didn't look that good.
............
.........
};

Does C++ guarantee that my memcpy always make an exact duplicate of
Object 'b' no matter how big the class is.
C++ guarantees NOTHING when it comes to C library functions. That's C's
job to guarantee those. And since C knows NOTHING about classes, the use
of memcpy with non-POD types is _undefined_.


I see your point. My question should have been, does C++ guarantees that
object's allocated
memory would be continuous? But, now I do understand the problems especially
if there are
virtual functions.
Is this a general way of writing copy constructors?
Of course not. First of all what you wrote is an assignment operator
and not a copy constructor. Second, using memcpy with classes (as I
already mentioned) is undefined. Third, it is extremely dangerous even
if it were defined. Trust me, you don't want go around copying class
objects using memcpy. Just use copy construction semantics for all your
data. If it's a dynamic array, copy it by allocating and then by using
std::copy on it.

Also, class A as you wrote (a) does not copy the array pointed to by
the member 'ptr' (and instead just allocates it and leaves it alone)
and (b) lacks any other construction. Perhaps you didn't want to write
other [irrelevant] things, but when dynamic memory management is used,
the "rule of three" has to be followed (or else).
2. Null Reference.


No such thing exists.
For example we have a function that searches a list and returns a pointer
to an object if it is found or NULL if it can't find the object. How can
I do this if I want to return a reference instead of a pointer, without
throwing exceptions?


You can't.
3. This code is from FAQ lite.

class Point {
public:
static Point rectangular(flo at x, float y); // Rectangular coord's
static Point polar(float radius, float angle); // Polar coordinates
// These static methods are the so-called "named constructors"
...
private:
Point(float x, float y); // Rectangular coordinates
float x_, y_;
};

inline Point::Point(fl oat x, float y)
: x_(x), y_(y) { }

inline Point Point::rectangu lar(float x, float y)
{ return Point(x, y); }

inline Point Point::polar(fl oat radius, float angle)
{ return Point(radius*co s(angle), radius*sin(angl e)); }

int main()
{
Point p1 = Point::rectangu lar(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5. 7, 1.2); // Obviously polar
...
}

Dumb question. Now who owns p1 and p2 and how can I delete them?


They are automatic variables and will be disposed of at the end of
the 'main' function body. Nobody "owns" them and they don't need to
be explicitly deleted. Only objects created by 'new' need to be
'delete'd.


I see that question, in the context of the code, is really dumb.
Let me give modified code

class Point {
public:
static Point* instance();
private:
static Point* _instance;
Point();
float x_, y_;
};

inline Point* Point::instance ()
{
if(_instance == 0){
_instance = new Point();
}
return _instance;
}

inline Point::Point( )
: x_(0), y_(0) { }

Point* Point::_instanc e=0;

int main()
{
Point* p1 = Point::instance () ;
.......
}

Now who owns p1 and how can I delete it.

What book are you reading that doesn't talk about copy construction
and automatic variables?
Actually I am not reading any book. I know I should. I know C and
am working on C++ from that experience. I know C++ is different but then it
is similar too. I got Stroustrup's book and will start reading soon.

V
Thanks V for you reply

Jul 23 '05 #7
Victor Bazarov wrote:

Well, you can return a reference to NULL, [..]

How?

Not that any sane programmer would do this (but that apparently only
rules out about 10% of us)... I've seen some stupid...er "heroic"
things tried in order to fit into just the kinds of constraints the OP
mentioned - return a ref, no exceptions... IMHO that's a good time for
the designer/coder to "push back" on the requirements. But when they
can't/won't you end up with "stuff" like this:
#include<iostre am>

class foo
{
public:
void ident()
{
std::cout << "My address is: " << static_cast<voi d*>(this) <<
std::endl;
}
};
foo& stupidFunction( )
{
return *static_cast<fo o*>(NULL);
}
int main(int argc, char* argv[])
{
stupidFunction( ).ident();
return 0;
}
And a really bad "contract" with the caller of the function that they
have to check that the reference they get back is in fact a real object.
Ugh!!!
Jul 23 '05 #8
PS - I'm almost ashamed to post that dereference a cast of a NULL
code/construct. I don't want anyone to ever use it - so everyone forget
you ever saw it.

PPS - Drop the "almost" above...
Jul 23 '05 #9
MSR

"Phil Staite" <ph**@nospam.co m> wrote in message
news:rs******** ************@pc isys.net...
MSR wrote:
class A {
private:
int a1;
double d1;
char *ptr;

public:
const A* operator=(const A* b)
{
memcpy(this, b, sizeof(A));
ptr = new char[100];
};

};

Does C++ guarantee that my memcpy always make an exact duplicate of
Object 'b' no matter how big the class is. Is this a general way of
writing copy constructors?
Yes, memcpy makes an exact copy of the memory pointed to but...

NO, NO, NOOOOOOO This is not the general way of writing copy
constructors!!! Besides, what you coded is the assignment operator. Well,
sort of. Usually they deal with const references to the source object,
not pointers.

Consider these problems:

A alpha;
alpha = &alpha; // hint, think memory leak

Consider passing a pointer to a class derived from A??? IIRC 'this'
points to *all* the storage for the object, and I believe in most
implementations the first thing there is the vtbl pointer. So your blind
memcpy will step on the A's vtbl pointer and point it at the derived
class's vtbl. Madness surely lies down this path... I know I know, your
example doesn't have virtual methods but I'm being general here. And in
general, memcpy is a bad idea in C++.

A more usual copy constructor for A would look something like:

A( const A& src ) : a1(src.a1), d1(src.d1), ptr(NULL)
{
if(src.ptr != NULL)
{
ptr = new char[ std::strlen(src .ptr) + 1 ];
std::strcpy(ptr ,src.ptr);
}
}

And an assignment operator would look like:

A& operator=( const A& src )
{
if( &src != this ) // check for self-assignment
{
a1 = src.a1;
d1 = src.d1;
delete[] ptr;
if( src.ptr == NULL )
ptr = NULL;
else
{
ptr = new char[ std::strlen(src .ptr) + 1 ];
std::strcpy(ptr ,src.ptr);
}
}
return *this;
}


Thanks. I see the problems with memcpy. My main motivation for using
memcpy instead of copying member one by one was, my objects are
pretty big and I wanted avoid typing which by the way is error prone.
But it looks like there is no easy way out

2. Null Reference. For example we have a function that searches a list
and returns a pointer to an object if it is found or NULL if it can't
find the object. How can I do this if I want to return a reference
instead of a pointer, without throwing exceptions?
Well, you can return a reference to NULL, but then the burden is on the
code making the call to remember to check and see if the & of the
reffered-to object is NULL. (blech)

Bite the bullet, throw exceptions.

Don't return references.

Create a default and plug it in, return that reference.

Have a static "blank" or default no-value-found object and return a
reference to it.


Ok. I didnt read this.
3. This code is from FAQ lite.

class Point {
public:
static Point rectangular(flo at x, float y); // Rectangular
coord's
static Point polar(float radius, float angle); // Polar coordinates
// These static methods are the so-called "named constructors"
...
private:
Point(float x, float y); // Rectangular coordinates
float x_, y_;
};

inline Point::Point(fl oat x, float y)
: x_(x), y_(y) { }

inline Point Point::rectangu lar(float x, float y)
{ return Point(x, y); }

inline Point Point::polar(fl oat radius, float angle)
{ return Point(radius*co s(angle), radius*sin(angl e)); }

int main()
{
Point p1 = Point::rectangu lar(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5. 7, 1.2); // Obviously polar
...
}

Dumb question. Now who owns p1 and p2 and how can I delete them?


The local scope within the main() function owns the objects. Short
answer - you don't delete them. The compiler generates code that deletes
them (off the stack, not the heap!) when the function exits/returns. (or
throws an exception)

Jul 23 '05 #10

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

Similar topics

4
7180
by: franky.backeljauw | last post by:
Hello, I have a problem with using a copy constructor to convert an object of a templated class to object of another templated class. Let me first include the code (my question is below): <code:templates.h> #include <string> #include <iostream>
42
5820
by: Edward Diener | last post by:
Coming from the C++ world I can not understand the reason why copy constructors are not used in the .NET framework. A copy constructor creates an object from a copy of another object of the same kind. It sounds simple but evidently .NET has difficulty with this concept for some reason. I do understand that .NET objects are created on the GC heap but that doesn't mean that they couldn't be copied from another object of the same kind when...
4
1818
by: away | last post by:
1. When a class defined with a member of pointer type, it's necessary to have a copy constructor and assignment operator. If don't pass objects of such class as value in a function and don't do assignment, should copy constructor and assignment operator be unnecessary? 2. If a base class have a pointer member, should its derived classes also need copy constructor and assignment operator, no matter if a derived class itself has a...
3
1931
by: Matt Bitten | last post by:
Hi, all. I have the same old problem about templates and copy constructors. I know this has been addressed hundreds of times, but despite perusing many old postings, and The Standard as well, I'm still feeling confused. Suppose I have a class template: template <typename T> class Foo {
10
2589
by: utab | last post by:
Dear all, So passing and returning a class object is the time when to include the definition of the copy constructor into the class definition. But if we don't call by value or return by value, we do not need to use the copy-constructor. So depending on the above reasoning I can avoid call by value and return by value for class objects, this bypasses the problem or it seems to me like that. Could any one give me some simple examples...
8
449
by: rKrishna | last post by:
I was trying to understand the real need for copy constructors. From literature, the main reason for redfinition of copy constructor in a program is to allow deep copying; meaning ability to make copies of classes with members with static or dynamic memory allocation. However to do this it requires the programmer to override the default copy constructor, the destructor & operator=. I wrote a small program to test if i can doa deep copy...
10
3456
by: JurgenvonOerthel | last post by:
Consider the classes Base, Derived1 and Derived2. Both Derived1 and Derived2 derive publicly from Base. Given a 'const Base &input' I want to initialize a 'const Derived1 &output'. If the dynamic type of 'input' is Derived1, then 'output' should become a reference to 'input'. Otherwise 'output' should become a reference to the (temporary) result of the member function 'input.to_der1()' which returns a Derived1 object by value.
22
3636
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 v);
7
6427
by: Peter Olcott | last post by:
Why can a union have a member with a copy constructor?
0
9933
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
9787
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10734
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10838
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10408
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7119
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
4607
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4212
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3230
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.