簡體   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