2011-07-19 1247 views
10

我正在閱讀C++教程,但實際上並沒有給我兩者之間的區別(除了語法)。這裏是教程的引用。顯式賦值vs隱式賦值

您也可以在聲明時爲變量賦值。當我們 賦值使用賦值運算符的變量(等於 號),它被稱爲一個明確的賦值:

int nValue(5); // implicit assignment 

int nValue = 5; // explicit assignment 

您還可以使用隱式分配給變量賦值儘管隱式賦值看起來很像函數調用,但編譯器會跟蹤哪些名稱是變量,哪些是 函數,以便可以正確解析它們。

是否有區別?比另一個更受歡迎嗎?

+5

這不是一個聲明,它的定義。溝教程和[閱讀一本體面的書](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。用C++進行思考是免費的,可以從作者的頁面獲得。 –

+3

@Cat Plus Plus:這是一個定義,但這並不意味着它不是一個聲明。 –

+1

@JamesMcNellis:它應該是一個教程,調用定義聲明無助於擺脫兩者之間的混淆。也許我今天只是胡思亂想而已。 :+ –

回答

10

第一個是基本類型,如int;第二種是具有構造函數的類型,因爲它使構造函數調用顯式化。

例如,如果您已經定義了一個class Foo,可以從一個單一的int構造,然後

Foo x(5); 

優於

Foo x = 5; 

(你需要前者的語法比反正多的時候一個參數被傳遞,除非你使用的是Foo x = Foo(5, "hello");,這很簡單,看起來像operator=被調用。)

+4

值得一提的是,使用構造語法時,您需要小心最棘手的分析。 –

+4

另請注意,如果'Foo :: Foo(int)'沒有標記爲'explicit',則'Foo x = 5'纔會起作用。 – Vitus

+0

...(繼續@Vitus評論)和'Foo'拷貝構造函數是可訪問的。 –

1

當你聲明一個變量並對其進行初始化時,它們在功能上與上下文相同。我通常是指兩個爲:

int nValue = 5; // assignment syntax 

int nValue(5); // construction syntax 

基本類型,我更喜歡建設任務,因爲它是更加自然,尤其是對於那些誰在其他語言編程。

對於類類型,我更喜歡構造語法,因爲它避免了構造函數的存在。

+1

標準(N3242)調用語法'T x = a' *複製初始化*和'T x(a)'*直接初始化*。兩者都是調用構造函數'T :: T(a)'的有效方式。 –

5

對於原始類型都是等價的,它對於用戶定義的類類型是有差別的。在這兩種情況下,執行的代碼都是相同的(在執行基本優化之後),但如果我們正在初始化的元素不是我們正在構建的類型,則對類型的要求會有所不同。

複製初始化T t = u;)相當於從臨時T類型已被隱式地從u轉換爲t的複製結構。另一方面,直接初始化相當於直接調用相應的構造函數。

雖然在大多數情況下,不會有任何區別,如果採取u構造函數聲明explicit或者如果拷貝構造無法訪問,然後複製初始化將失敗:

struct A { 
    explicit A(int) {} 
}; 
struct B { 
    B(int) {} 
private: 
    B(B const &); 
}; 
int main() { 
    A a(1);  // ok 
    B b(1);  // ok 
// A a2 = 1; // error: cannot convert from int to A 
// B b2 = 1; // error: B(B const &) is not accessible 
} 

對於一些歷史背景,初始原始類型必須用複製初始化進行初始化。當* initializer-list *被添加到語言中以初始化類中的成員屬性時,決定使用與保持初始化程序列表中的語法統一且簡單的類相同的語法來初始化基本類型。同時允許通過複製初始化對類進行初始化,使得用戶定義的類型更接近原始類型。兩種初始化格式的區別很自然:int a = 5.0;被處理爲從5.0int的轉換,然後從int初始化a。用戶定義類型也是如此:T u = v;作爲從vT的轉換處理,然後從該轉換後的值中複製u的構造。