1.什麼時候聲明同時也是定義,什麼時候只是聲明?
相同點:
C++和Java中使用一個標識符之前必須對其進行聲明.但是標識符的聲明和定義不是一回事兒.
定義是指分配了內存空間.
不同點:
C++中只是聲明而非定義的示例如下:
extern int error_num; //使用外部變量的聲明
class Student; //類的前向聲明(不完整聲明)
double d( double ); //被調用函數的聲明
C++中大多數情況下聲明的同時進行了定義(即分配了內存空間),無論是全局變量還是局部變量,還有對象的數據成員.
int j;
int count = 1; //聲明,定義,初始化爲一體.
string s; //C++創建對象的時候既聲明又定義,當然其成員也會定義.但是進行類類型的聲明時不會分配內存.
Java中聲明是否同時爲定義有兩種情況,如int a;
(1).如果a爲一個方法的局部變量(無初始值)的話,則其只是一個聲明而非定義(即不分配內存).
如果希望在聲明一個局部變量的同時爲其定義,則可以對其進行初始化.如int a = 1;
(2),如果a爲一個類的數據成員的話,則其既是聲明又是定義(即分配內存).
2,C++和Java中的變量是否在定義的時候進行了缺省初始化?
相同點:
C++和Java中都存在對定義的變量進行初始化的機制,只是具有不同的規則,同時缺省初始化時都是將變量初始化爲適當的0.
不同點:
C++中只對於兩種類型的數據作出缺省的初始化:
(1).作爲全局變量的基本類型.
(2).具有一個無參構造函數的類類型的對象,會根據其無參的構造函數來進行缺省的初始化.
具體的規則是:
整型 0 , 浮點型 0.0 , 布爾型 false (0) ,字符型 '\0' ,
類類型 取決於其無參構造函數.
說明1:
如果沒有提供一個無參構造函數,此時有兩種情況:
(1).同時也沒有其他的構造函數的話,系統會爲類提供一個缺省的無參構造函數,雖然按照規則進行初始化,但是隻進行了內存分配而不進行初始化,所以指針成員會出現垃圾信息.
(2).同時定義了其他的構造函數,只是沒有一個無參的構造函數,這是系統不會自動提供無參的構造函數,
此時 形如 類名 + 對象名; 這種方式將會出錯.
如果一個類中包含了未初始化的const或者引用成員,系統將不會提供一個缺省的無參構造函數.只能提供一個自定義的無參構造函數進行顯式地初始化.
Java中變量在定義時的缺省初始化規則:
只有一種情況:一個變量首次在函數的內部出現且沒有爲其賦予初始值的話(即爲一個方法的局部變量(無初始值))都是聲明而非定義.
整型 0, 單精度 0.0f , 雙精度 0.0 , 字符型 \ u0000, 布爾型 false (0), 對象引用 null.
注意:
類名 + 對象 ; 在java中只是聲明而不定義(分配內存空間),其值爲null,不能直接使用.
類名 + 對象 = new 類名(...); 纔是聲明和定義,分配內存空間,可以直接使用.
C++的代碼示例:
- #include <iostream>
- using namespace std;
- //定義全局變量,被缺省初始化爲適合的0
- int iNum1;
- bool bNum1;
- char cNum1;
- float fNum1;
- double dNum1;
- class CMyClass1
- {
- private:
- int m_i;
- int m_j;
- public:
- CMyClass1()
- {
- m_i = 10;
- m_j = 20;
- }
- CMyClass1(int i,int j)
- {
- m_i = i;
- m_j = j;
- }
- void Show()
- {
- cout<< " m_i = " << m_i << endl;
- cout<< " m_j = " << m_j << endl <<endl;
- }
- };
- class CMyClass2
- {
- public:
- CMyClass2(int &x,int y,int z):m_x(x),m_y(y)
- {
- m_z = z;
- }
- void Show()
- {
- cout<< " m_x = " << m_x << endl;
- cout<< " m_y = " << m_y << endl;
- cout<< " m_z = " << m_z << endl;
- }
- protected:
- private:
- int & m_x;
- const int m_y;
- int m_z;
- };
- void main()
- {
- int iNum2;
- cout<< " iNum1 = " << iNum1 <<endl;
- cout<< " iNum2 = " << iNum2 <<endl << endl;
- bool bNum2;
- cout<< " bNum1 = " << bNum1 <<endl;
- cout<< " bNum2 = " << bNum2 <<endl << endl;
- char cNum2;
- cout<< " cNum1 = " << cNum1 <<endl;
- cout<< " cNum2 = " << cNum2 <<endl << endl;
- float fNum2;
- cout<< " fNum1 = " << fNum1 <<endl;
- cout<< " fNum2 = " << fNum2 <<endl << endl;
- double dNum2;
- cout<< " dNum1 = " << dNum1 <<endl;
- cout<< " dNum2 = " << dNum2 <<endl << endl;
- CMyClass1 myClass1;
- myClass1.Show();
- CMyClass1 myClass2(); //錯誤地調用了無參構造函數,其實是一個返回值類型爲CMyClass的函數的聲明
- //myClass2.Show();
- CMyClass1 myClass3(30,40);
- myClass3.Show();
- //CMyClass2 myClass4;
- int num1 = 1;
- CMyClass2 myClass5(num1,2,3);
- myClass5.Show();
- }