這是我們寫Shape s = new Circle();
其中Shape
是abstract class
一個面試問題。Shape s = new Circle()之間的區別是什麼?和Shape * s = new Circle();
是什麼s
和形狀類型的像Shape * s = new Circle();
指針之間的差異?
這是我們寫Shape s = new Circle();
其中Shape
是abstract class
一個面試問題。Shape s = new Circle()之間的區別是什麼?和Shape * s = new Circle();
是什麼s
和形狀類型的像Shape * s = new Circle();
指針之間的差異?
這兩句話彼此截然不同,我會用簡單的(正確)一個第一:
Shape * s = new Circle();
正如你已經提到,s
是在這種情況下指針到Shape
。該聲明聲明s
,併爲其指定Circle
類型的指針。這意味着Circle
源自Shape
。
由於C++是一種多態語言,因此s
現在指向Circle
類型的對象。如果Shape
有virtual functions由Circle
超載,要求對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++是一種危險的語言,即使它們看起來起初工作,你也可以做很多非常錯誤的事情。
好的答案,我也建議給原始的海報,如果這些概念混淆,那麼它可能不是正確的時間採訪C++工作! –
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
具有虛擬析構函數,以便可以安全地刪除其派生類型。
問題中是否提及特定語言? –
大概這是一個[tag:C++]問題 - 但請編輯您的問題並添加適當的語言標記。 –
是的,它是C++的問題。 –