简体   繁体   中英

Do pointers have copy constructors?

I am transiting from C pointers to C++ ones,now learning about auto_ptr. Here is the program I tried:

#include <iostream>
#include <memory>
#include "Car.h"
using namespace std;
typedef auto_ptr<Car> CarPtr;
int main() {
    CarPtr au_ptr1(new Car());
    CarPtr au_ptr2 = new Car();
    Car *norm_ptr1 = new Car();
    Car *norm_ptr2(new Car());
    int *i_ptr1=new int();
    int *i_ptr2(new int());
}

Statements like the following mean what?

int *i_ptr2(new int());
Car *norm_ptr2(new Car()); 

The statement mentioned above compiled successfully.And the following one,throws a compilation error - CarPtr au_ptr2 = new Car(); Why is that?

Thanks in Advance

It does have a copy constructor, but the conversion constructor is explicit , which is what is causing the error:

explicit auto_ptr (X* p=0) throw();

Which means a Car* can't be implicitly converted to a auto_ptr<Car> , which is what

CarPtr au_ptr2 = new Car();

attempts to do. This is called copy-initialization , as opposed to:

CarPtr au_ptr1 (new Car());

which is value-initialization . The first version will attempt to create a temporary CarPtr from a Car* and use it to initialize au_ptr2 . The second one calls the copy constructor directly.

Statements like

int *i_ptr2(new int());

simply value-initialize the pointer with the value in the parenthesis.

Typically objects have copy constructor and pointers are not objects so they don't have copy constructor (or assignment operator or destructor). More precisely, pointers rely on the default copying mechanism.

When you talk about auto_ptr or any other smart pointers, they are just pointer namesakes. But in actual they are templatized objects which use the RAII mechanism.

CarPtr au_ptr2 = new Car();  // this is initialization not assignment

gives compilation error because corresponding CarPtr::CarPtr(...) constructor is made explicit , so it doesn't accept the = style initialization.

Raw pointers don't have constructors, but for most purposes they can be used as if they do. The built-in types can all be initialized from a value of any type convertible to their type, just like a user-defined class with a copy constructor can.

int *i_ptr1=new int();
int *i_ptr2(new int());

mean the same thing.

I think the reason for this is basically templates: it means that you can use a type T as though it were a user-defined type, and write T t(0); or T(0) or T() , and when T happens to be a built-in type the meaning is exactly the same as T t = 0; or (T)0 or (T)0 (again). Actually, the meaning of T(0) is by definition the same as (T)0 regardless of what constructors T has, but people who tell you not to use C-style casts in C++ code try to ignore that fact ;-)

auto_ptr does in fact have a copy constructor, but unlike most copy ctors it takes a non-const parameter, and modifies its argument. That's why in C++11 it's deprecated in favor of unique_ptr , which doesn't have a copy constructor but does have a move constructor.

As Luchian says, the problem with CarPtr au_ptr2 = new Car(); isn't (just) the copy constructor, it's also the lack of an implicit conversion from the type of new Car(); , Car* , to auto_ptr<Car> . Copy initialization tries to implicitly convert the RHS to the type of the LHS, and then copy it to the LHS. Both of those fail in this example. Direct initialization is allowed to use explicit conversions and doesn't need a copy, so it succeeds.

One way in which built-in types don't behave as if they have constructors is default initialization. You can write:

int i = int();

and i is guaranteed initialized to zero. So you might imagine that it has a no-args constructor that sets it to zero. But if int were really a class type with that constructor, then writing:

int i;

would also guarantee i is zero, and it doesn't (at least, not in function scope).

By the way, don't get too excited by all this and accidentally invoke the so-called "most vexing parse".

int i();

is equivalent to int i(void); , not int i(0); . It declares a function, not an integer variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM