• Advertisement
Sign in to follow this  

pointers

This topic is 4184 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have an instance where i need to take a pointer, create a new pointer using "new" and copy the values from the passed pointer into the new one so the old one can be deleted and the new one will retain the values from the old one.

Share this post


Link to post
Share on other sites
Advertisement
Assuming C++. Implement a copy constructor for your class then just do:


MyClass *newPointer = new MyClass( *oldPointer );

//since the values have been copied
//you can happily delete the old instance without data loss
delete oldPointer;


here's a little tut on Copy Constructors: http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html

-me

Share this post


Link to post
Share on other sites
What you described is usually referred to as 'cloning.' It's a common idiom in C++.

You have to write a clone() member function yourself. Yuo can sometime leverage the copy constructor.

Share this post


Link to post
Share on other sites
A _very_ important thing to remember is that if your class has member variables which are pointers, those variables will also have to be copy-constructed.

-me

Share this post


Link to post
Share on other sites
Quote:
Original post by EvilKnuckles666
so i would have to create my own copy constructor and copy constructor those pointers as well?


correct. if you just assign the values of the member variable pointers then you're just copying a memory address, not the data itself. So you'll have to implement copy-constructors for all the member variable objects also. If they're dynamically allocated arrays, you'll have to new [] and then memcpy the data, etc.

-me

Share this post


Link to post
Share on other sites
does this look correct?

class myClass
{
myClass(myClass &Copy)
{
m_pOne = *Copy.m_pOne;
m_pTwo = *Copy.m_pTwo;
m_Three = Copy.m_Three;
};

// ...

};

Share this post


Link to post
Share on other sites
The "deep copy" issue is one of the most problamatic in all of programming, because there is no such thing as a "correct" one-size-fits-all solution.

But for your case I think you want to implement either the "deepest copy reasonable" / "copy everything I can create" version or the "copy everything I own" version. I would start with the "copy everything I own" version.

Which simply means this, every single thing you destroy in your destructur, you should create a new copy instance of in your assignment operator and copy constructor.

So if you destructor does this:

delete x;
// or something like this:
x.Dispose();
x = null;

in your copy functions you should use:

x = new XsType(*(rhs.x));

not:

x = rhs.x;

Share this post


Link to post
Share on other sites
ok, i got that much, but how do i copy a value from one pointer to the value of another?

i thought this: but it doesn't work

*newpointer = *oldpointer

Share this post


Link to post
Share on other sites
what's wrong with this code? it's giving me an error


myClass(myClass &Copy)
{
m_pOne = NULL;
m_pTwo = NULL;

memcpy((void*)m_pOne , (void*)Copy.m_pOne, sizeof(myClass));
memcpy((void*)m_pTwo , (void*)Copy.m_pTwo, sizeof(myClass));
m_Three= Copy.m_Three;
};

Share this post


Link to post
Share on other sites
You are writing to two NULL pointers, which is a Bad ThingTM. Have these pointers point to something beforehand.

Also, you seem to be memcpy'ing classes. This is a Worse ThingTM, since classes often have no definite memory layout and/or contain pointers. Classes should be copied using their copy constructor.

Share this post


Link to post
Share on other sites
Never use memcpy to copy classes!

You're telling it to write to a NULL memory address, twice. You will be getting a NULL pointer exception.

Your solution will look like the following.
newpointer = new myInternalClass(*oldpointer);

Share this post


Link to post
Share on other sites
only bad thing is when i call that "new" i'd have to delete it too, and i wouldn't know which instances i copied from and which one's i created and didn't use "new" so i woudln't know which ones to call "delete" on

Share this post


Link to post
Share on other sites
Remember that you don't have to call new or delete for every pointer variable you use. You have to call new and delete for every dynamicly allocated value you use. You could have multiple pointers point to the same object, but you only need to use new and delete once.

I could be wrong, but I get the impression that you're lacking a basic understanding of pointers and freestore memory. I'd recommend looking up tutorials on that.

Share this post


Link to post
Share on other sites
The point is you're not supposed to assign the created objects to another class, you should create new ones.


class A {
public:
A() {
member0 = 0;
}

A(const A &src) {
member0 = src.member0;
}

private:
int member0;
}


class B {
public:
B() {
member0 = new A;

member1 = new int[10];
for(int i=0;i<10;i++)
member1 = 0;

member2 = 0;
}

B(const B &src) {
member0 = new A(*src.member0);

member1 = new int[10];
for(int i=0;i<10;i++)
member1 = src.member1;

member2 = src.member2;
}

~B() {
delete member0;
delete[] member1;
}

private:
A *member0;
int *member1
int member2;
}




This way you can just create a copy of your class with
B *newB = new B(*oldB);

Additionaly it's better to use initalization lists, if you know what those are.

If you don't want to create new copies of the objects inside the class you should not make a copy, but rather a swap.
Create a new empty class object, then swap the internal variables with the old one, and then delete the old one.

Share this post


Link to post
Share on other sites
ok... there's no way i'm going to be able to do this because i can't get a hold of the class at all.... it's an API struct.

here's what i'm REALLY trying to do.. maybe someone can help.

ok, i have a template that has an Add() function, internally it adds to a map<> template with a std::string and Type (the template part). the Add() created a new item using "new" and puts it into the map<>. BUT now what i'm trying to do is make an Insert() that lets you put a pointer to an already created object and add that into the map<> but i noticed when i get that object back, it doesn't have the values i put in it. here's my code.


void Insert(std::string str, Type* Item)
{
Type *newType = new Type(*Item); // this is where i want to have a point
// get created and have the same values
// as the old one

m_MapList.insert( std::pair<std::string, Type*>(str, newType));
};




this would work and all, but because of the struct i'm using that apart of an API, i can't get a hold of the copy structure. sooo... is there another way i could do it with the map<> maybe?

thanks

edit: sry, i had other stuff that wasn't right in there

Share this post


Link to post
Share on other sites
So are you saying the class you are using does not have a copy-constructor / assignment operator?

If the API class you are using IS copyable - then you could use either a std::map<std::string, Type> or std::map<std::string, Type*> depending on the semantics you want for ownership, and the efficiency you need to achieve.

std::map<std::string, Type> would always use value / copy semantics

std::map<std::string, Type*> would use reference semantics by default, but if you implemented it as you showed above (using new Type(...)) then you are getting value semantics with a pointer.

If the API class you are using is not copyable, then you cannot copy it. Therefore your only choice is std::map<std::string, Type*> AND you cannot make it have value semantics (because you cannot call new) ... you can ONLY use reference semantics ... so you would need to deal with ownership management issues rather than copy-creation issuse.

For instance you could use a smarter pointer .... many to choose from, but boost seems to be the way to go ...

then when you Add() the element, you do whatever management required of your smart poitner (often nothing but strait assignment).

Share this post


Link to post
Share on other sites
my template is defined as map<std::string, Type*>, i'm using all pointers. doing so there's no way of taking a value from one, creating a new one and putting those values into my map?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement