2016年Adobe認證面試題
Adobe 的客户包括世界各地的企業、知識工作者、創意人士和設計者、OEM 合作伙伴,以及開發人員。下面一起來看看Adobe的認證考試題庫,希望對大家有所幫助!
what is the rule of class D_*, UserCalss, and client class of D_* and UserClass to access the member of class B
class B{/*... ...*/};
class D_pri:private B{/*... ...*/};
class D_publ:public B{/*... ...*/};
class UserClass{ B b; /*... ...*/}
D_pri: 私有繼承自B,那麼B中的public, private, protected在D_pri中修改為private,
“private繼承會將基類中的public和protected可見性的成員修改成為private可見性,這樣一來雖然派生類中同樣還是可以調用基類的protected和public成員,但是在派生類的派生類就不可以再調用被private繼承的基類的成員了。” from here
D_publ: 公有繼承自B,B中的三種類型在這個派生類中保持不變,派生類可以調用基類的protected和public成員,但是無法調用private成員
UserClass: 有一個B的對象b,b可以訪問b中的public成員函數及成員變量,但是無法訪問private和protected成員函數與變量
==========================我是問題分割線==========================
write the output:
[cpp] view plain copy print?
#include
#include
using namespace std;
void println(const string& msg)
{
cout<
}
class Base
{
public:
Base() { println("Base::Base()"); virt(); }
void f() { println("Base::f()"); virt(); }
virtual void virt() { println("Base::virt()"); }
};
class Derived :public Base
{
public:
Derived() { println("Derived::Derived()"); virt(); }
virtual void virt() { println("Derived::virt()"); }
};
void main()
{
Derived d;
cout<<"-------------------"<
Base *pB = &d;
pB->f();
}
output:
Base::Base()
Base::virt()
Derived::Derived()
Derived::virt()
-------------------
Base::f()
Derived::virt()
很少會在構造函數和析構函數中調用虛函數,因為在它們中調用的虛函數將失去“多態”功能
==========================我是問題分割線==========================
static_cast 和 dynamic_cast有什麼區別:
static_cast 沒有運行時類型檢查來保證轉換的'安全性;
dynamic_cast 用於類層次間(有繼承關係的)的向上或者向下類型轉換,也可以在兄弟類別中進行轉換,它的安全性由RTTI來保證;
特別是當處理向下類型轉換時用static_cast貌似成功轉換的結果也許會造成遭難, 若無法進行向下類型轉換dynamic_cast會返回NULL.
參考:點擊打開鏈接
《Thinking in C++》
==========================我是問題分割線==========================
const char *p
char const *p;
前兩個的意思是一樣的,都是表示指向只讀(const)char型變量的指針,所以不能進行 *p = 2; 這類修改被指對象值的操作
char * const p;
指針p是隻讀的,指針的值不能修改,比如p++不可以。
const char const *p;
這個指針即指向只讀類型char的變量,本身又是隻讀的
==========================我是問題分割線==========================
下面類的兩種構造函數有什麼區別
Sample::Sample(string name):_name(name){}
Sample::Sample(string name):{_name=name;}
----------------------------------------------我是回答分割線----------------------------------------------------
第一個調用了string的拷貝構造,
第二個比較麻煩,先調用string的默認構造函數,然後調用賦值操作符的重載函數
--------------------------------------------------測試代碼---------------------------------------------------------
[cpp] view plain copy print?
class A
{
int _counter;
public:
A() {cout<<"in A()"<
A(int i):_counter(i) {_counter= 0 ;cout<<"in A(int i)"<
A(const A &a) {_counter = a._counter; cout<<"A(const A &a)"<
A& operator = (const A &a)
{
if(this == &a )
return *this;
_counter = a._counter;
cout<<"in A& operator = (const A &a) "<
return *this;
}
};
class B
{
A _a;
public:
B(A &a)
{
_a = a;
}
};
void main()
{
A a(1);
cout<<"=============================="<
B b(a);
}
輸出結果:
in A()
in A& operator = (const A &a)
==========================我是問題分割線==========================
空類的系統自動產生的函數(至少寫四個)
默認構造函數;
默認拷貝構造函數;
默認的operator = 函數
析構函數
上述這幾個是確認的,
還有一個取值函數: const Empty* operator&() const; 這個我還不太確認
==========================我是問題分割線==========================
怎樣防止類被繼承?對於不能被繼承的類,怎樣初始化及銷燬它的示例呢?
我的第一想法就是將構造函數私有化,然後用靜態成員函數在堆上新建實例,
如果將析構函數也私有化,那麼需要一個靜態成員函數來做‘善後’工作
貌似這也符合提議,更加複雜的方法可見:猛點我
--------------------------------------------------測試代碼---------------------------------------------------------
[cpp] view plain copy print?
class uninheritable
{
int _value;
uninheritable(int v): _value(v){}
~uninheritable() {};
public:
static uninheritable *create(int v);
static void delete_uninherit(uninheritable* uninherit);
};
uninheritable* uninheritable::create(int v)
{
return new uninheritable(v);
}
void uninheritable::delete_uninhert(uninheritable* uninherit)
{
if( uninherit )
{
delete uninherit;
uninherit = NULL;
}
}
可以這麼寫,編譯通過
class derived : public uninheritable
{
// add what you want the class to do
};
但是,如果你想初始化derived類的一個對象,那麼編譯器報錯,因為基類的構造函數是私有的,派生類的構造函數無法調用基類的私有成員函數
==========================我是問題分割線==========================
產生繼承類實例時構造函數的調用次序(基類包含虛函數,繼承類重寫了)
基類構造函數先被調用,然後再調用派生類的構造函數,而且基類構造函數在派生類構造函數的初始化列表中被調用,
如果有繼承自多個基類,那麼按照public A,B,C的依次順序,而不是在初始化列表中的順序。
貌似這題很簡單啊,但是為什麼強調“基類包含虛函數,繼承類重寫了”
想來想去只有虛函數表指針的初始化問題,所以應該是這樣:
設置基類vptr, 然後執行基類構造函數的初始化列表,執行基類構造函數體,
再進行派生類初始化列表中其他初始化(比如先進行成員對象,再內建類型初始化,假設有),然後派生類的vptr初始化,然後進入派生類構造函數體。
還要再查權威的C++書。
==========================我是問題分割線==========================
手工實現 strcpy 函數,不能使用任何庫函數,要求處理 NULL、溢出等異常:
可能以下函數沒有完全符合題意,模仿了strncpy這個函數
[cpp] view plain copy print?
/*
Description: Copies the first num characters of source to destination
dst:
Pointer to the destination array where the content is to be copied.
src
string to be copied.
num
Maximum number of characters to be copied from source.
*/
char* mystrncpy(char *dst, const char *src, size_t num)
{
if( NULL == dst )
return NULL;
if( NULL == src )
return dst;
const char *pSrc = src;
char *pDst = dst;
int max_num = num;
while( *pSrc != '