c++面試題整理(二)

13.“引用”與多態的關係?

引用是除指針外另一個可以產生多態效果的手段。這意味着,一個基類的引用可以指向它的派生類實例。例4

Class A; Class B :

Class A{...};

  B b; A& ref = b;

14.“引用”與指針的區別是什麼?敲打

指針通過某個指針變量指向一個對象後,對它所指向的變量間接操作。程序中使用指針,程序的可讀性差;而引用本身就是目標變量的別名,對引用的操作就是對目標變量的操作。此外,就是上面提到的對函數傳ref和pointer的區別。

15.什麼時候需要“引用”?

流操作符<<和>>、賦值操作符=的返回值、拷貝構造函數的參數、賦值操作符=的參數、其它情況都推薦使用引用。

16.結構與聯合有和區別?吐舌頭

(1). 結構和聯合都是由多個不同的數據類型成員組成, 但在任何同一時刻, 聯合中只存放了一個被選中的成員(所有成員共用一塊地址空間), 而結構的所有成員都存在(不同成員的存放地址不同)。 
(2). 對於聯合的不同成員賦值, 將會對其它成員重寫, 原來成員的值就不存在了, 而對於結構的不同成員賦值是互不影響的。

17.面關於“聯合”的題目的輸出?大笑

a)

#include <stdio.h>
union
{
int i;
char x[2];
}a;
void main()
{
	a.x[0] = 10; 
	a.x[1] = 1;
	printf("%d",a.i);
}

答案:266 (低位低地址,高位高地址,內存佔用情況是Ox010A)

b)

#include<stdio.h>
int main() 
{ 
	union{                   /*定義一個聯合*/ 
	   int i; 
	   struct{             /*在聯合中定義一個結構*/ 
			char first; 
			char second; 
		}half; 
	}number;
	
	number.i=0x4241;         /*聯合成員賦值*/ 
	printf("%c%cn", number.half.first, mumber.half.second); 
	number.half.first='a';   /*聯合中結構成員賦值*/ 
	number.half.second='b'; 
	printf("%xn", number.i); 
	getch(); 
	return 0;
} 

 答案: AB   (0x41對應'A',是低位;Ox42對應'B',是高位)      

6261 (number.i和number.half共用一塊地址空間)

18.關聯、聚合(Aggregation)以及組合(Composition)的區別?睡覺

涉及到UML中的一些概念:關聯是表示兩個類的一般性聯繫,比如“學生”和“老師”就是一種關聯關係;聚合表示has-a的關係,是一種相對鬆散的關係,聚合類不需要對被聚合類負責,如下圖所示,用空的菱形表示聚合關係:從實現的角度講,聚合可以表示爲:

class A {...}  class B { A* a; .....}

而組合表示contains-a的關係,關聯性強於聚合:組合類與被組合類有相同的生命週期,組合類要對被組合類負責,採用實心的菱形表示組合關係:實現的形式是:

class A{...} class B{ A a; ...}

19.面向對象的三個基本特徵,並簡單敘述之?

1. 封裝:將客觀事物抽象成類,每個類對自身的數據和方法實行protection(private, protected,public)

2. 繼承:廣義的繼承有三種實現形式:實現繼承(指使用基類的屬性和方法而無需額外編碼的能力)、可視繼承(子窗體使用父窗體的外觀和實現代碼)、接口繼承(僅使用屬性和方法,實現滯後到子類實現)。前兩種(類繼承)和後一種(對象組合=>接口繼承以及純虛函數)構成了功能複用的兩種方式。

3. 多態:是將父對象設置成爲和一個或更多的他的子對象相等的技術,賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。

 

20.重載(overload)和重寫(overried,有的書也叫做“覆蓋”)的區別?生氣

常考的題目。從定義上來說:

重載:是指允許存在多個同名函數,而這些函數的參數表不同(或許參數個數不同,或許參數類型不同,或許兩者都不同)。

重寫:是指子類重新定義父類虛函數的方法。

從實現原理上來說:

重載:編譯器根據函數不同的參數表,對同名函數的名稱做修飾,然後這些同名函數就成了不同的函數(至少對於編譯器來說是這樣的)。如,有兩個同名函數:function func(p:integer):integer;和function func(p:string):integer;。那麼編譯器做過修飾後的函數名稱可能是這樣的:int_func、str_func。對於這兩個函數的調用,在編譯器間就已經確定了,是靜態的。也就是說,它們的地址在編譯期就綁定了(早綁定得意),因此,重載和多態無關!

重寫:和多態真正相關。當子類重新定義了父類的虛函數後,父類指針根據賦給它的不同的子類指針,動態的調用屬於子類的該函數,這樣的函數調用在編譯期間是無法確定的(調用的子類的虛函數的地址無法給出)。因此,這樣的函數地址是在運行期綁定的(晚綁定奮鬥)。

21.多態的作用?害羞

主要是兩個:

1. 隱藏實現細節,使得代碼能夠模塊化;擴展代碼模塊,實現代碼重用;

2. 接口重用:爲了類在繼承和派生的時候,保證使用家族中任一類的實例的某一屬性時的正確調用。

22.Ado與Ado.net的相同與不同?驚恐

除了“能夠讓應用程序處理存儲於DBMS 中的數據”這一基本相似點外,兩者沒有太多共同之處。但是Ado使用OLE DB 接口並基於微軟的COM 技術,而ADO.NET 擁有自己的ADO.NET 接口並且基於微軟的.NET 體系架構。衆所周知.NET 體系不同於COM 體系,ADO.NET 接口也就完全不同於ADO和OLE DB 接口,這也就是說ADO.NET 和ADO是兩種數據訪問方式。ADO.net 提供對XML 的支持。

23.New delete 與malloc free 的聯繫與區別?

答:都是在堆(heap)上進行動態的內存操作。用malloc函數需要指定內存分配的字節數並且不能初始化對象,new 會自動調用對象的構造函數。delete 會調用對象的destructor,而free 不會調用對象的destructor.

24.#define DOUBLE(x) x+x ,i = 5*DOUBLE(5); i 是多少?

答案:i 爲30。

25.有哪幾種情況只能用intialization list 而不能用assignment? 鄙視

答案:當類中含有const、reference 成員變量;基類的構造函數都需要初始化表。

26. C++是不是類型安全的?

答案:不是。兩個不同類型的指針之間可以強制轉換(用reinterpret cast)。C#是類型安全的。

27. main 函數執行以前,還會執行什麼代碼?睡覺

答案:全局對象的構造函數會在main 函數之前執行。

#include<iostream>
using namespace std;

class A{
public:
	A(){cout<<"構造函數!"<<endl;}
};

A a;

int main(){
	cout<<"主函數!"<<endl;
	return 0;
}


//構造函數,主函數

28. 描述內存分配方式以及它們的區別?罵人

1) 靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static 變量
2) 在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集。
3) 從堆上分配,亦稱動態內存分配。程序在運行的時候用malloc 或new 申請任意多少的內存,程序員自己負責在何時用free 或delete 釋放內存。動態內存的生存期由程序員決定,使用非常靈活,但問題也最多。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章