Assignment Operator Issues

Now, let's look at the next line: s = n;. That looks harmless enough; it just copies one string, n, to another string, s. But wait a second; how does the compiler know how to assign a value to a variable of a type we've made up?

Just as the compiler will generate a version of the default constructor if we don't define one, because every object has to be initialized somehow, the ability to assign one value of a given type to a variable of the same type is essential to being a concrete data type. Therefore, the compiler will supply a version of operator =, the assignment operator, if we don't define one ourselves. In Chapter 6, we were able to rely on the compiler-generated operator =, which simply copies every member variable from the source object to the target object. Unfortunately, that won't work here. The reason is that the member variable m_Data isn't really the data for the string; it's a pointer to (i.e., the address of) the data. The compiler-generated operator =, however, wouldn't be able to figure out how we're using m_Data, so it would copy the pointer rather than the data. In our example, s = n;, the member variable m_Data in s would end up pointing to the same place in memory as the member variable m_Data in n. Thus, if either s or n did something to change "its" data, both strings would have their values changed, which isn't how we expect variables to behave.

To make this more concrete, let's look back at Figure 7.8. So far, we have an object of type string that contains a length and a pointer to dynamically allocated memory where its actual data are stored. However, if we use the compiler-generated operator = to execute the statement s = n;, the result looks like Figure 7.11.

Figure 7.11. strings n and s in memory after compiler-generated =


In other words, the two strings s and n are like Siamese twins; whatever affects one of them affects the other, since they share one copy of the data "Test". What we really want is two strings that are independent of one another, so that we can change the contents of one without affecting the other one. Very shortly, we'll see how to accomplish this.

As you might suspect, Susan didn't think the need for us to define our own operator = was obvious at all. Here's how I started talking her into it.

Susan: I have a little note to you off to the side in the margins about this operator =, it says "If it was good enough for native data then why not class data?" I think that is a very good question, and I don't care about that pointy thing. I don't understand why m_Data isn't really data for the string.

Steve: It isn't the data itself but the address where the data starts.

Susan: Actually, looking at these figures makes this whole idea more understandable. Yes, I see somewhat your meaning in Figure 7.11; that pointy thing is pointing all over the place. Oh no, I don't want to see how to make two independent strings! Just eliminate the pointy thing and it will be all better. OK?

Steve: Sorry, that isn't possible. You'll just have to bear with me until I can explain it to you better.

Susan: Well, let me ask you this: Is the whole point of writing the statement s = n just to sneak your way into this conversation about this use of operator =? Otherwise, I don't see where it would make sense for the sample program.

Steve: Yes, that's correct.

Susan: And the chief reason for creating a new = is that the new one makes a copy of the data using a new memory address off the free store, rather than having the pointer pointing to the same address while using the compiler-generated operator =? If so, why? Getting a little fuzzy around that point. With StockItem, the compiler-generated operator = was good enough. Why not now?

Steve: Yes, that's why we need to create our own operator =. We didn't need one before because the components of a StockItem are all concrete data types, so we don't have to worry about "sharing" the data as we do with the string class, which contains a char*.

Susan: So when you use char* or anything with a pointer, that is outside the realm of concrete data types?

Steve: Right. However, the reason that we can't allow pointers to be copied as with the compiler-generated operator = isn't that they aren't concrete data types, but that they aren't the actual data of the strings. They're the address of the actual data; therefore, if we copy the pointer in the process of copying a variable, both pointers hold the same address. This means that changes to one of the variables affects the other one, which is not how concrete data types behave.

Susan: I think I actually understand this now. At least, I'm not as confused as I was before.

Steve: Good; it's working.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset