Jump to content
Larry Ullman's Book Forums

Why Copy Objects? [Chapter: More Advanced Oop]


Recommended Posts

Guest Deleted

I was just reading the sidebar on page 197, which talks about cloning and copying objects, and I was wondering why anybody would want to copy an object. It seems like when you do that, you have the exact same object, just you can get at it through two different variables.

 

Look:

$user1 = new User();
$user1->username = 'Billy-Bob';
$user1->user_id = 55;
$user2 = $user1;

It seems that all I have achieved is I can now get at Billy-Bob's info through $user2 in addition to $user1.

 

Can somebody explain why I'd want to do something like this?

 

I was never great at advanced OOP, so please forgive me if I sound like an idiot for asking this, lol. Also, I did look this up on Google but all I could find was people talking about how to copy an object, not why to copy one :(

Link to comment
Share on other sites

Guest Deleted

Thanks for trying but that's one of the pages I found on Google. It didn't help because it didn't explain why I would want to copy (deep copy). It goes into a little bit about why you would want to clone (shallow copy), but not why you would copy. I'm curious why anybody would want two variables referencing the same instance of an object. 

Link to comment
Share on other sites

I'm curious why anybody would want two variables referencing the same instance of an object. 

I think you should ask the opposite question.

In most cases, it's fine for multiple variables to reference the same object in memory. This is the default behavior in pretty much all mainstream languages, including PHP.

 

In fact, in PHP 4, a new copy was made every time an object was assigned to another variable, but the creators of PHP realized that it was very inefficient to do things that way, so in PHP 5, they changed the language so that (unless explicitly declared otherwise with the clone keyword), multiple variable copies of an object would all reference the same object in memory.

 

This default behavior of object referencing in most languages is that way because it's a lot more efficient and quicker to do things that way. You may not realize this, but there are very rarely cases that you actually need two physical copies of an object in memory, but when you do, you can do it by cloning the object. Again, though, those cases are rare, so the default behavior (rightfully so) is to just reference one object in memory with multiple variables.

 

Also, just out of curiosity, have you already looked at this page as well?

http://php.net/manual/en/language.oop5.cloning.php

Link to comment
Share on other sites

The most basic and yet most important knowledge to gather here is values versus references. Make sure you understand that first and foremost, as it's very important. $user2 and $user1 references the same object in your example. The variables are simply pointers. Think of the object as a balloon and the variables as Strings tying it to the ground. Both variables references the same balloon, and will change the same balloon. Without any references (variables) a balloon will fly up (be garbage collected) into the atmosphere.

 

Object copying is an edge-case as Jon says. If you need a lot of very similar, but still slightly different objects, this may be such a case where copying can save a lot of resources. On a general basis, you don't really have to think about the problem. As long as you understand the reference-vs-value logic, you're pretty much good to go in most cases.

  • Upvote 1
Link to comment
Share on other sites

Guest Deleted

If needing to copy an object is so rare, then should I just forget about trying to understand why you'd want to do it? As for how to do it, I think I've got that down.

 

Here's a script I threw together to test my copying and cloning knowledge. Do I seem to be understanding correctly?

 

class Dog {


private $_breed;
private $_name;


public function __construct($name, $breed)
{
$this->_name = $name; 
$this->_breed = $breed;
}


public function show_info()
{
echo '<p><b>Name:</b> '.$this->_name.' <b>Breed:</b> '.$this->_breed.'<p/>'; 
}


public function change_name($new_name)
{
$this->_name = $new_name; 
}


}
//create original
$dog1 = new Dog('Shaggy', 'Irish Wolfhound');
$dog1->show_info();


//copy
$dog2 = $dog1;
$dog2->change_name('Rex');
$dog1->show_info();
$dog2->show_info(); //same output as dog1


//clone
$dog3 = clone $dog1;
$dog3->change_name('Duke');
$dog1->show_info();
$dog3->show_info(); //different output from dog1

Output:

Name: Shaggy Breed: Irish Wolfhound

 

Name: Rex Breed: Irish Wolfhound

 

Name: Rex Breed: Irish Wolfhound

 

Name: Rex Breed: Irish Wolfhound

 

Name: Duke Breed: Irish Wolfhound

 

 

Thanks.

Link to comment
Share on other sites

Yes, your understanding seems fine.

I didn't mean to imply that cloning is super rare either, but rather, there are situations in which it is essential, but in a vast majority of situations (whether you realize it or not), cloning is unnecessary, and thus a waste of resources.

As such, the default behavior is for variables to reference objects by pointing to an object, which is in a different location in memory.

Link to comment
Share on other sites

Guest Deleted

Which is not super rare? Cloning or copying?

 

And are you talking about cloning as in $dog1 = clone $dog3; or cloning as in copying like I did with $dog1 = $dog2? I want to make sure I understand your personal terminology.

Link to comment
Share on other sites

Both are pretty rare. I've not had a problem that required object copying or cloning yet. Larry can probably think of a case where it would be needed, but I can't currently. As long as you know how to copy, and understand references-vs-values, I would say you are good to go. You'll remember what to do if you ever meet such a problem later on. It's pretty specialized.

Link to comment
Share on other sites

To me, "copying an object" and "cloning an object" mean exactly the same thing.

 

I think the reason cloning is rare is because most of the time, if you need another object of a certain class, you'll just use the new keyword to instantiate a new instance of the class, as opposed to cloning an existing instance of the class.

Again, I'm not saying you would never clone something, but I've never had to.

Link to comment
Share on other sites

Guest Deleted

Antonio: Okie.

 

Harley: Ah ok so you don't make a distinction between the two. Gotcha.

 

How about shallow copy and deep copy? Do you distinguish between those?

Link to comment
Share on other sites

Guest Deleted

What do you mean by subobject? Like, when you pass an object to another object?

 

Untested example:

require('list.php');
require('sortbyalpha.php');

$array = array(
'number' => 5,
'number' => 1,
'number' => 17,
'number' => 19,
'number' => 2,
);

$list = new List($array);
$list->sort(new SortByAlpha('descending'));
Link to comment
Share on other sites

No, a subobject is if you have an object that contains other objects as properties. For example, you might have a Department object with an internal array (an attribute) of employees. Each element in the array would be an object of type Employee. A shallow copy would only copy the Department object and any non-object attributes. A deep copy or clone would also copy the array of Employee objects. This would require a lot more memory, which is why it's not the default.

Link to comment
Share on other sites

Guest Deleted

Oh, ok! I've seen that before. I didn't know those were subobjects. Okie dokie.

 

What if an object doesn't have any subobjects, but it does have defined properties. You can still do a deep or a shallow copy of it, right?

Link to comment
Share on other sites

Guest Deleted

Hmm, so then if not having subobjects makes everything just a copy, then how do we distinguish between when we use the clone keyword and when we do not? In my example in reply #7 I made two copies of objects: one without the clone keyword and one with it. The resulting copies behaved differently. What terminology would I use to explain what I did?

Link to comment
Share on other sites

Copies are only created when you use the clone keyword. It breaks down like this:

 

Normal assignment (i.e., without the clone keyword): A reference to an existing object is assigned to the variable.

 

Shallow copy: Object contains subobjects, but only a copy of the main object is created.

 

Deep copy: Object contains subobjects, and all subobjects are copied as well.

 

Copy (no distinction between shallow and deep): Object contains no subobjects and is copied using the clone keyword.

  • Upvote 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...