2014-06-11 228 views

回答

2

這兩句話彼此截然不同,我會用簡單的(正確)一個第一:

指針

Shape * s = new Circle(); 

正如你已經提到,s在這種情況下指針到Shape。該聲明聲明s,併爲其指定Circle類型的指針。這意味着Circle源自Shape

由於C++是一種多態語言,因此s現在指向Circle類型的對象。如果Shapevirtual functionsCircle超載,要求對s將被重定向到超載Circle實現這些功能。

簡單和不完整例子(注意,在C++中,有no by-keyword definedabstract classes):

class Shape{ 
    virtual int getX() = 0; //getX() is purely virtual, so Shape is abstract 
} 
class Circle : public Shape{ 
    int getX() override; 
} 

Shape * s = new Circle(); 

int myX = s->getX(); //will call Circle::getX() 

這是基本的多態行爲,和麪向對象編程的C++中的基石之一。另外請注意,override keyword不是完全必要的,我個人認爲它是很好的風格。

的對象

Shape s = new Circle(); 

這種說法看起來幾乎像第一位的,但確實完全不同的東西。首先,s現在是實際的對象,同時好壞。這很好,因爲一旦剩下當前compound statement它就會自動銷燬,釋放它所佔用的所有內存。

但這很糟糕,因爲s不能再多態化:它被聲明爲Shape -Object,沒有別的。用上面的代碼,並且你的前提Shape是一個抽象類,那甚至都不起作用。抽象類不能實例化,因爲它們沒有實現函數。

如果我們認爲它不是抽象的,我們會陷入很多隱式轉換的漏洞,我只希望在很短的方式來描述的:

爲了上述說法是正確的C++碼,Shape需要有一個構造函數Circle*類型的一個說法,那就是聲明爲explicit。這將使Shape s = new Circle();等於Shape s = Shape(new Circle());implicit conversion發生。

這是非常非常糟糕的代碼! new Circle()爲無法釋放的Circle對象分配內存,因爲它沒有名字!這就是所謂的內存泄漏,這就是爲什麼你幾乎應該使用從未在C++中使用裸指針。另一種方法叫smart pointers,你應該儘可能使用它們。

此外,爲了防止這樣的事情發生,你應該申報所有構造函數explicit(或者至少是隻取一個參數的那些):

explicit Shape(Circle *); 

最後,我想鼓勵你去read at least one, better a few books about C++。我剛剛解釋的所有內容都是你應該真正瞭解的超級基本內容,而這不是學習它的最佳地方。 C++是一種危險的語言,即使它們看起來起初工作,你也可以做很多非常錯誤的事情。

+0

好的答案,我也建議給原始的海報,如果這些概念混淆,那麼它可能不是正確的時間採訪C++工作! –

1

new Circle創建一個類型爲Circle的動態對象並給出一個指針。該指針可用於初始化指向Circle或任何基類Circle的指針;所以假設Circle導出從Shape,第二形式

Shape * s = new Circle; 

給出的(靜態)類型Shape*,指向的對象(動態)型Circle的指針。這可以多形地使用,通過由Shape定義的抽象接口與Circle交互,而不需要知道實際類型是Circle

第一,不正確的,例如

Shape s = new Circle; 

嘗試創建Shape類型的對象,與指針初始化爲Circle。作爲抽象的,Shape不能被實例化,除了作爲派生類的一部分,所以這不能編譯。

當您使用new時,請務必在完成動態對象時記住delete,或者更好的是使用智能指針等類,以便爲您處理那些容易出錯的乏味。此外,請確保Shape具有虛擬析構函數,以便可以安全地刪除其派生類型。

相關問題