Why reference is used in copy constructor
Line 15 begins the call to f h , this time ignoring the return value. You can see in line 16 that the copy-constructor is called just as before to pass the argument in. And also, as before, line 21 shows the copy-constructor is called for the return value. But the copy-constructor must have an address to work on as its destination a this pointer. Where does this address come from?
It turns out the compiler can create a temporary object whenever it needs one to properly evaluate an expression. Finally, in lines , the h2 object is destroyed, followed by h , and the object count goes correctly back to zero.
Suppose you create a new class composed of objects of several existing classes. The example demonstrates what the compiler does while creating the default copy-constructor for your new class:. The class WithCC contains a copy-constructor, which simply announces that it has been called, and this brings up an interesting issue.
In the class Composite , an object of WithCC is created using a default constructor. If there were no constructors at all in WithCC , the compiler would automatically create a default constructor , which would do nothing in this case. The class WoCC has no copy-constructor, but its constructor will store a message in an internal string that can be printed out using print.
The reason for this becomes apparent later. The class Composite has member objects of both WithCC and WoCC note the embedded object wocc is initialized in the constructor-initializer list, as it must be , and no explicitly defined copy-constructor. However, in main an object is created using the copy-constructor in the definition:.
The copy-constructor for Composite is created automatically by the compiler, and the output of the program reveals the way that it is created:. To create a copy-constructor for a class that uses composition and inheritance, which is introduced in Chapter 14 , the compiler recursively calls the copy-constructors for all the member objects and base classes.
That is, if the member object also contains another object, its copy-constructor is also called. So in this case, the compiler calls the copy-constructor for WithCC. The output shows this constructor being called. Because WoCC has no copy-constructor, the compiler creates one for it that just performs a bitcopy, and calls that inside the Composite copy-constructor. The call to Composite::print in main shows that this happens because the contents of c2.
The process the compiler goes through to synthesize a copy-constructor is called memberwise initialization.
This guarantees that it will be under your control. At this point your head may be swimming, and you might be wondering how you could have possibly written a working class without knowing about the copy-constructor. So how do I know that an object will never be passed by value? If the user tries to pass or return the object by value, the compiler will produce an error message because the copy-constructor is private.
Reference syntax is nicer to use than pointer syntax, yet it clouds the meaning for the reader. Instead, the function call looks like a pass-by-value, which suggests the outside object is not modified. If you always pass addresses as const references except when you intend to modify the outside object via the address, where you pass by non- const pointer, then your code is far easier for the reader to follow.
A pointer is a variable that holds the address of some location. You can change what a pointer selects at runtime, and the destination of the pointer can be either data or a function. To understand this syntax, consider a simple structure, with a pointer sp and an object so for this structure. You can select members with the syntax shown:. Now suppose you have an ordinary pointer to an integer, ip. Finally, consider what happens if you have a pointer that happens to point to something inside a class object, even if it does in fact represent an offset into the object.
Now, what is the syntax for defining pointerToMember? The only difference is that you must say what class of objects this pointer-to-member is used with. Of course, this is accomplished with the name of the class and the scope resolution operator. You can also initialize the pointer-to-member when you define it or at any other time :. Obviously, these are too awkward to use anywhere except for special cases which is exactly what they were intended for.
Also, pointers to members are quite limited: they can be assigned only to a specific location inside a class. You could not, for example, increment or compare them as you can with ordinary pointers.
A similar exercise produces the pointer-to-member syntax for member functions. A pointer to a function introduced at the end of Chapter 3 is defined like this:. Parentheses also play an important role when defining and using pointers to member functions. If you have a function inside a class, you define a pointer to that member function by inserting the class name and scope resolution operator into an ordinary function pointer definition:.
In the definition for fp2 you can see that a pointer to member function can also be initialized when it is created, or at any other time. However, you can give the function identifier without an argument list, because overload resolution can be determined by the type of the pointer to member. The value of a pointer is that you can change what it points to at runtime, which provides an important flexibility in your programming because through a pointer you can select or change behavior at runtime.
A pointer-to-member is no different; it allows you to choose a member at runtime. Typically, your classes will only have member functions publicly visible data members are usually considered part of the underlying implementation , so the following example selects member functions at runtime.
If the user must directly manipulate a pointer-to-member, then a typedef is in order. To really clean things up, you can use the pointer-to-member as part of the internal implementation mechanism. All the user needs to do is pass a number in to select a function. In the class interface and in main , you can see that the entire implementation, including the functions, has been hidden away.
The code must even ask for the count of functions. This way, the class implementer can change the quantity of functions in the underlying implementation without affecting the code where the class is used. The main reason of this is that, if we pass object to the copy constructor it will create a copy of that object and this will again call a copy constructor and this will happen recursively and this will goes in infinite loop.
Because of this copy constructor use references. No Account? Sign up. By signing in, you agree to our Terms of Use and Privacy Policy. Already have an account? Sign in. By signing up, you agree to our Terms of Use and Privacy Policy.
Enter the email address associated with your account. We'll send a magic link to your inbox. Email Address. All Sign in options. Enter a Email Address. Default initialization Value initialization Zero initialization Copy initialization Direct initialization. Expressions Value categories Order of evaluation. Operators Operator precedence. Class declaration Constructors this pointer. Access specifiers friend specifier. Class template Function template. Inline assembly. Compiler support. Freestanding and hosted.
Language support library. Technical specifications. Flow control. Function declaration. Lambda function declaration.
Fundamental types. Function types. Compound types. Storage duration specifiers. Default initialization. Value initialization. Zero initialization. Copy initialization. Direct initialization. Aggregate initialization. Constant initialization. Reference initialization. Value categories. Order of evaluation.
0コメント