[英]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.