繁体   English   中英

指针是否具有复制构造函数?

[英]Do pointers have copy constructors?

我正在从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构造,因此它不接受=样式初始化。

原始指针没有构造函数,但是对于大多数目的,它们可以像使用它们一样使用。 内置类型都可以从可转换为其类型的任何类型的值初始化,就像带有复制构造函数的用户定义类一样。

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

意思是一样的。

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

实际上, auto_ptr确实具有一个复制构造函数,但是与大多数复制ctor不同,它使用一个非const参数,并修改其参数。 这就是为什么在C ++ 11中不赞成使用unique_ptr ,后者没有副本构造函数,但确实具有move构造函数。

如Luchian所说, CarPtr au_ptr2 = new Car();的问题CarPtr au_ptr2 = new Car(); 不只是复制构造函数,还缺少new Car();类型的隐式转换new Car(); Car*auto_ptr<Car> 复制初始化尝试将RHS隐式转换为LHS的类型,然后将其复制到LHS。 两者均在此示例中失败。 直接初始化允许使用显式转换,并且不需要副本,因此可以成功。

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

int i = int();

并且i保证初始化为零。 因此,您可能会想到它具有一个无参数的构造函数,将其设置为零。 但是如果int实际上是具有该构造函数的类类型,则编写:

int i;

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

顺便说一句,不要对所有这些都太兴奋,而会意外地调用所谓的“最令人烦恼的解析”。

int i();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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