指针有复制构造函数吗

Do pointers have copy constructors?

本文关键字:构造函数 复制 指针      更新时间:2023-10-16

我正在从C指针过渡到C++指针,现在正在学习auto_ptr。这是我尝试过的程序:

#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());
}

像下面这样的陈述意味着什么?

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

上面提到的语句编译成功。下面的一个,抛出编译错误-CarPtr au_ptr2 = new Car();为什么?

提前感谢

它确实有一个复制构造函数,但转换构造函数是显式的,这就是导致错误的原因:

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

这意味着Car*不能隐式转换为auto_ptr<Car>,这就是

CarPtr au_ptr2 = new Car();

尝试执行。这被称为复制初始化,而不是:

CarPtr au_ptr1 (new Car());

这是值初始化。第一个版本将尝试从Car*创建临时CarPtr,并使用它来初始化au_ptr2。第二个直接调用复制构造函数。

等报表

int *i_ptr2(new int());

简单地用括号中的值初始化指针。

通常对象有复制构造函数,指针不是对象,所以它们没有复制构造函数(或赋值运算符或析构函数)。更确切地说,指针依赖于默认的复制机制。

当您谈到auto_ptr或任何其他智能指针时,它们只是指针的同名者。但实际上,它们是模板化对象,使用RAII机制。

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

给出编译错误,因为对应的CarPtr::CarPtr(...)构造函数被设置为explicit,所以它不接受=风格的初始化。

Raw指针没有构造函数,但在大多数情况下,它们可以像有构造函数一样使用。内置类型都可以从任何可转换为其类型的值初始化,就像具有复制构造函数的用户定义类一样。

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

意思是一样的。

我认为这基本上是因为模板:这意味着你可以像使用用户定义的类型一样使用类型T,并编写T t(0);T(0)T(),当T恰好是内置类型时,其含义与T t = 0;(T)0(T)0完全相同(再次)。实际上,无论T有什么构造函数,T(0)的含义都与(T)0相同,但那些告诉你不要在C++代码中使用C风格转换的人试图忽略这一事实;-)

auto_ptr实际上有一个复制构造函数,但与大多数复制构造函数不同,它采用了一个非常量参数,并修改了它的参数。这就是为什么在C++11中,它被弃用,而支持unique_ptr,它没有复制构造函数,但有移动构造函数。

正如Luchian所说,CarPtr au_ptr2 = new Car();的问题不仅在于复制构造函数,还在于缺乏从类型new Car();Car*auto_ptr<Car>的隐式转换。复制初始化尝试将RHS隐式转换为LHS的类型,然后将其复制到LHS。这两种方法在本例中都失败了。直接初始化允许使用显式转换,并且不需要副本,因此它成功了。

内置类型的行为不像有构造函数一样的一种方式是默认初始化。你可以写:

int i = int();

并且保证CCD_ 28被初始化为零。因此,您可以想象它有一个无args构造函数将其设置为零。但是,如果int真的是一个具有该构造函数的类类型,那么写:

int i;

也可以保证i为零,但它不是(至少不在函数范围内)。

顺便说一句,不要对这一切太兴奋,也不要意外地调用所谓的"最麻烦的解析"。

int i();

相当于int i(void);而不是int i(0);。它声明了一个函数,而不是一个整数变量。