2013-11-28 129 views
1

我有一個函數定義爲返回一個空當返回類型不是指針

ClassType f(int i) { 
    if (...) return NULL; 
    ... 
    ClassType obj; 
    return obj; 
} 

我很好奇,爲什麼一個「NULL」可以當一個類類型是必需的返回類型在法律上接受?我認爲NULL通常被宏定義爲'0'的同義詞。有人可以解釋這背後的理由嗎?謝謝!

更新:

的類定義爲:

class ClassType { 
public: 
    ClassType() {}; 
    ClassType(char* s) {...}; 
... 
} 

一個問題,請問C++做隱式轉換時,由價值迴歸?

謝謝!

+0

ClassType是如何定義的? ,我; m對構造函數感興趣? – Raxvan

+0

@Raxvan您認爲的隱式轉換? – Nik

+0

@Nik是,隱式轉換。 – Raxvan

回答

3
class ClassType { 
public: 
    ClassType() {}; 
    ClassType(char* s) {...}; // <<----- 
} 

,我打上使用時,你說return NULL;構造函數。該值可隱式轉換爲char*NULL通常定義爲0,這是一個有效的指針值)。

還有一個問題,C++在返回值時做了隱式轉換嗎?

是的,因爲它必須構造合適類型的對象。

+5

爲了補充說明,可以在構造函數聲明中用'explicit'關鍵字來防止這種情況的發生。 – ypnos

+1

在C++中'NULL'不能是'(void *)0'。它必須是一個值爲'0'或'nullptr'的整型常量表達式。 – Simple

+0

@簡單你是對的,解決了這個問題。謝謝。 – jrok

1

首先,在這種情況下,你可以返回NULL,因爲編譯器會再使用ClassType(char* s)構造與NULL的構造函數參數傳遞。

但是一般情況下,對於像這樣的情況,您可能希望將該對象作爲引用參數傳遞給函數,然後返回布爾值truefalse函數是否成功。

1

Null是一個用0定義的宏,它是一個整數值。如果該類好好嘗試一下有一個構造函數,可以採取0,則編譯器將拋出一個

class ClassType 
{ 
public: 
    ClassType(const int); 
}; 

:如果ClassType有一個接受整數或指針則構造函數,編譯器會自動轉換成整數0至ClassType錯誤。

+0

'NULL'不一定只是'0'。 – chris

+0

@chris c版本將它定義爲((void *)0),但是在那裏你不能有可以用於隱式轉換的構造函數。一些編譯器可能會以不同的方式處理NULL,但隱式轉換應該仍然有效。據我所知,爲了解決這個問題,在C++ 11中添加了nullptr。 – Raxvan

+0

C99將'NULL'定義爲空指針常量。這只是一個空指針常量的可能性。但是,是的,引入'nullptr'來清除這個問題。有趣的一點是'#define NULL nullptr'對於實現AFAICT是合法的。 – chris

0

不準確地回答你的問題,但一般來說,要表明可選的返回值,請考慮以下事項。


對於情況下,可選的返回值是有道理的,你可能會考慮boost::optional,和C++ 14將有可能定義std::optional(基於增壓庫)。在diguise表示成功

附加返回值,如bool S,經常會在你不能只有在情況下,你可以初始化對象的負擔,如果你想返回一個可選的值,對於這個有沒有默認的構造,你不能,或者你必須傳遞引用指針,然後必須在被調用的站點上檢查指針等。:

std::optional<Intensity> sample_spectrum (float); // clean and concise 

------------------------------------------------------------------------- 

bool sample_spectrum (Intensity &out); // either not possible or you 
             // have a wasted initialization 

------------------------------------------------------------------------- 

bool sample_spectrum (Intensity *& out) { // now you have two problems 
    if (!out) throw std::logic_error(""); // I 
    .... 
} 
.... 
    try { .... } catch (...) { .... }  // II 

------------------------------------------------------------------------- 

Intensity *sample_spectrum(float) ; // please no 

------------------------------------------------------------------------- 

std::shared_ptr<Intensity> 
    sample_spectrum(float); // just use std/boost::optional