導航:首頁 > 源碼編譯 > 編譯器是如何聲明一個類的

編譯器是如何聲明一個類的

發布時間:2022-09-01 19:03:08

⑴ C#中用private聲明一個類是什麼意思

private 是修飾符
它和protected, public一起,都是對類的訪問許可權進行修飾,或者說是限制,
private,只有類內可直接訪問,

partial關鍵字的作用是將你的 class 分為多個部分,編譯器會將多個部分拼到一起去。
例子:
public partial class SampleClass
{
public void MethodA()
{
}
}

public partial class SampleClass
{
public void MethodB()
{
}
}



public class SampleClass
{
public void MethodA()
{
}
public void MethodB()
{
}
}
是等價的.

⑵ 和用class聲明一個類,有什麼區別

類的聲明只是告訴編譯器有這么一個類,它的名字是XXX,它具有哪些成員函數,哪些成員變數;而定義類是通過實例化類,對其分配存儲空間。聲明和定義最大的分別是是否分配存儲空間。 例如,這是類的聲明: class Student { public: 公用的數據和成員函數 protected: 保護的數據和成員函數 private: 私有的數據和成員函數 };//摘自網路 這是定義類:Student A = new Student();//分配了存儲空

java中函數的聲明和定義

Java中,我們應該知道最基本的就是定義變數和聲明變數了,那麼定義與聲明這兩者有沒有區別呢?具體的區別又是哪些呢?下面學習啦小編來告訴你定義與聲明的區別。

定義和聲明的定義區別

1、一種是需要建立存儲空間的。例如:int a 在聲明的時候就已經建立了存儲空間。

2、另一種是不需要建立存儲空間的。 例如:extern int a 其中變數a是在別的文件中定義的。

聲明是向編譯器介紹名字--標識符。它告訴編譯器「這個函數或變數在某處可找到,它的模樣象什麼」。

而定義是說:「在這里建立變數」或「在這里建立函數」。它為名字分配存儲空間。無論定義的是函數還是變數,編譯器都要為它們在定義點分配存儲空間。

對於變數,編譯器確定變數的大小,然後在內存中開辟空間來保存其數據,對於函數,編譯器會生成代碼,這些代碼最終也要佔用一定的內存。

總之就是:把建立空間的聲明成為「定義」,把不需要建立存儲空間的成為「聲明」。

基本類型變數的聲明和定義(初始化)是同時產生的;而對於對象來說,聲明和定義是分開的。

下面小編給大家舉個例子說明一下。

例如:類A

如果A a;就是一個聲明,告訴編譯器a是A類的一個對象變數,但是不進行初始化;

如果以後a=new A();這就是初始化,分配了空間。

需要注意的是我們聲明的最終目的是為了提前使用,即在定義之前使用,如果不需要提前使用就沒有單獨聲明的必要,變數是如此,函數也是如此,所以聲明不會分配存儲空間,只有定義時才會分配存儲空間。

用static來聲明一個變數的作用有二:

(1)對於局部變數用static聲明,則是為該變數分配的空間在整個程序的執行期內都始終存在。

(2)外部變數用static來聲明,則該變數的作用只限於本文件模塊。

定義和聲明的具體區別

所謂定義就是(編譯器)創建一個對象,為這個對象分配一塊內存,並給它取上一個名字,這個名字就是就是我們經常所說的變數名或對象名。

聲明有2重含義:

(1) 告訴編譯器,這個名字已經匹配到一塊內存上,下面的代碼用到變數或者對象是在別的地方定義的。聲明可以出現多次。

(2) 告訴編譯器,這個名字已經被預定了,別的地方再也不能用它來作為變數名或對象名。

定義和聲明最重要區別

定義創建對象並為這個對象分配了內存,聲明沒有分配內存。

⑷ 如何區分C++中類的聲明和定義

如果是指變數的聲明和定義:
從編譯原理上來說,聲明是僅僅告訴編譯器,有個某類型的變數會被使用,但是編譯器並不會為它分配任何內存。而定義就是分配了內存。
對於下面的兩句代碼:
void Func()
{
int a;
int b=1;
a=0;
}
對於第一行代碼,編譯器不會做任何事,它不會為它在棧中分配一點東西,直到第三句,a=0;時,編譯器才會將其壓入棧中。而對於int b=0;這一句,編譯器就會生成一條指令,為它賦值。如果反匯編,看到的代碼可能是這樣的:
push 1;
push 0;
當然,並不一定編譯器就會樣做,也有可能在聲明int a時,編譯器就會把一個廢值入棧,到第三條再為其賦值,這要看編譯器的具體取捨,所以,聲明不一定不是定義,而定義一定是定義。
但是,下面的聲明,一定僅僅是聲明:
extern int a;
這表時,有一個int變數a,它一定是在另外其他地方定義的,所以編譯器此時一定不會做什麼分配內存的事,因為它就是聲明,僅僅表明下面的代碼引用了一個符號,而這個符號是int類型的a而已。

如果是指函數的聲明和定義:
聲明:一般在頭文件里,對編譯器說:這里我有一個函數叫function() 讓編譯器知道這個函數的存在。
定義:一般在源文件里,具體就是函數的實現過程 寫明函數體。

⑸ 如何聲明類何為實例化

可以聲明一個類而不定義它
class Screen;//declaration of the Screen class
這個聲明,有時候被稱為前向聲明(forward declaration),在程序中引入了類類型的Screen.在聲明之後,定義之前,類Screen是一個不完全類型(incompete type),即已知Screen是一個類型,但不知道包含哪些成員.
不完全類型只能以有限方式使用,不能定義該類型的對象,不完全類型只能用於定義指向該類型的指針及引用,或者用於聲明(而不是定義)使用該類型作為形參類型或返回類型的函數.

對於C++中,類的定義之前聲明它,如下實例代碼:
class B;
class A{
//..............................
B * ptr_B;.
};
class B{
//....................
};
被提前聲明的類在其定義之前,只能使用該類的指針或者引用 。
在類的定義結束(編譯器在遇到類定義的右花括弧之後),用該類來聲明類實例對象,或對象指針,引用都是合法的。

前向聲明
超前引用

所謂超前引用是指一個類型在定義之前就被用來定義變數和聲明函數。
一般情況下,C/C++要求所有的類型必須在使用前被定義,但是在一些特殊情況下,這種要求無法滿足,
例如,在類CMyView中保留了一個非模式對話框對象指針,該對象用於顯示/修改一些信息。為了實現對話框
「應用」按鈕,把對話框做的修改立刻更新到view界面上,為此,需要在對話框類中需要保存view類的指針,這樣
定義關系就變成如下的代碼:

#ifndef __MYVIEW_H__
#define __MYVIEW_H__
//這是view類的頭函數
#include "MyDialog.h"
class CMyView::public CView
{
protected:
CMyDialog * pDlg;
//這里是其他定義
};
#endif

#ifndef __MYDIALOG_H__
#define __MYDIALOG_H__
//這是對話框類的定義
#include "MyView.h"
class CMyDialog::public CDialog
{
protected:
CMyView * pView;
//其他定義
};
#endif

從編譯器角度看,編譯MyDialog.CPP時,系統首先定義宏__MYDIALOG_H__,然後包含MyView.h,MyView.h中
的#include "MyDialog.h"由於__MYDIALOG_H__已經定義,所以不再起作用。在CMyView類的聲明中,
CMyDialog* pDlg ;
就會讓編譯器產生「CMyDialog"類型沒有定義之類的錯誤,編譯MyView.CPP文件出現的錯誤可以類似得到。

更一般的情況,類A和類B需要彼此互相引用,這樣必然有一個類會先被定義,而另外一個類後被定義,這樣在
先被定義的類引用後被定義的類的時候,就導致了所謂的超前引用。

超前引用導致的錯誤有以下幾種處理辦法:
1) 使用類聲明
在超前引用一個類之前,首先用一個特殊的語句說明該標識符是一個類名,即將被超前引用。其使用方法是:
a) 用class ClassB;聲明即將超前引用的類名
b) 定義class ClassA
c) 定義class ClassB;
d) 編制兩個類的實現代碼。
上述方法適用於所有代碼在同一個文件中,一般情況下,ClassA和ClassB分別有自己的頭文件和cpp文件,這種
方法需要演變成:
a) 分別定義ClassA和ClassB,並在cpp文件中實現之
b) 在兩個頭文件的開頭分別用class ClassB;和class ClassA;聲明對方
c) 在兩個cpp文件中分別包含另外一個類的頭文件
NOTE:這種方法切記不可使用類名來定義變數和函數的變數參數,只可用來定義引用或者指針。

2) 使用全局變數
由於全局變數可以避免超前引用,不用贅述。我的習慣是,把類對象的extern語句加在該類頭文件的最後,大家喜歡
怎樣寫那都沒有什麼大問題,關鍵是保證不要在頭文件中胡亂包含。
3) 使用基類指針。
這種方法是在引用超前引用類的地方一律用基類指針。而一般情況下,兩個互相引用的類並不涉及其基類,因此不會造成
超前引用。以開始的例子說:在CMyDialog類中用CView*代替CMyView*,在CMyView類中用CDialog*代替CMyDialog*,這樣必然
不會造成超前引用。

說明:本文中,為了敘述方便,把class AClass;語句成為類AClass的聲明,把class AClass開始的對AClass的類成員變數、
成員函數原型等的說明稱為類的定義,而把在CPP中的部分稱為類的定義。如果大家對這三個詞有不同的理解,請按照自己的本意
把這三個詞換成相應的詞來理解。

⑹ C++ 包括類的聲明、成員函數的實現

雖然很多程序員都熟悉名字空間的概念,但他們常常都是被動地使用名字空間。也就是說他們使用的是第三方定義的成員(如標准庫的類和函數),而不是在名字空間中聲明自己的類和函數。本文擬討論如何在名字空間中聲明自己的類和函數,以及如何在程序中使用它們。
名字空間是一個范疇,它包含類聲明,函數聲明,常量聲明和模板聲明等名字空間成員。例如:
namespace proj_alpha
{
//下面是名字空間 proj_alpha 的成員
class Spy {/*..*/};
void encrypt (char *msg);
const int MAX_SPIES = 8;
}
在上面的例子中,類Spy在一個單獨的文件中實現。通常,你是在一個專門的頭文件中聲明一個類並在不同的源文件中獨立地定義其成員函數。那麼如何將名字空間成員類分離成多個源文件呢?
下面是名為 Foo.hpp 的頭文件,其中定義了一個名為NS的名字空間,它包含類Foo的聲明:
//Foo.hpp
namespace NS
{
class Foo
{
public:
void f();
void g();
};
}//close NS
另外,在一個單獨的源文件Foo.cpp中,首先包含頭文件Foo.hpp以便實現類Foo的成員函數f()和g():
//Foo.cpp
#include "Foo.hpp"
void NS::Foo::f()
{ /*..*/ }
void NS::Foo::g()
{ /*..*/ }
為了使用名字空間成員,必須使用成員的全路徑名,它由名字空間後跟::合成原名組成。因此,類Foo的全路徑名是NS::Foo。這樣編譯器便可以知道NS是一個名字空間名,頭文件Foo.hpp必須在引用NS之前被包含。
名字空間是可以擴展的。也就是說可以聲明類,而且所聲明的類在其它的.cpp文件中是相同的名字空間成員:
//Bar.hpp
namespace NS //擴展 NS
{
class Bar
{
public:
void a();
void b();
};
}
在Bar.cpp文件中:
#include "Bar.hpp"
void NS::Bar::a()
{/*..*/}
void NS::Bar::b()
{/*..*/}
可以看出,雖然Foo和Bar這兩個類在不同的頭文件中聲明,但它們都是名字空間NS的成員。並且編譯器和鏈接器將這兩個類看成是同一名字空間的成員。那麼,如何在應用程序中使用這些類呢?
在文件main.cpp中,必須要包含聲明類Foo和Bar的頭文件並加上相應的名字空間引用聲明-using:
#include "Bar.hpp"
#include "Foo.hpp"
int main()
{
using NS::Bar; //使用名字空間
using NS::Foo; //同上
Bar b;
Foo f;
f.f();
//...
}
using聲明由關鍵字using後跟名字空間成員的全路徑。這樣就使你在using聲明範圍內使用成員時不用再加路徑。上面的例子中,可以直接使用Foo和Bar,因為在main()的開始使用了using聲明。如果沒有using聲明就必須使用全路徑成員名。
int main()
{
NS::Bar b; //全路徑名
NS::Foo f; //同上
//?
}
另外,還有一種引用名字空間成員的方法是使用using指令:
#include "Bar.hpp"
#include "Foo.hpp"
int main()
{
using namespace NS; // using 指令
Bar b;
Foo f;
f.f();
//...
}
using指令由關鍵字「using namespace」後跟名字空間名構成。在訪問名字空間成員時它是使用最少的一種方法,原因是這種方法將所有名字空間成員注入當前的范圍,從而增加了潛在的名字沖突。

⑺ c++中類的前向聲明.

在編譯時,編譯器必須知道每個類型的size,class a嵌套定義b p;但編譯器不知道p的大小,所以無法編譯。通過指針就可以了。

⑻ 發現一個聲明一個類的時候,比如role myrole和role myrole=null這兩種聲明是有區別的,請問具體區別

第一一個是全局變數的聲明才可以用,當然也可以用第二個,全局變數聲明用第一個時會默認給個初值,也就是第二個的情況。局部變數申明只能用第二個,其實沒有為什麼,是編譯器的默認,記得這么使用就可以了。

⑼ C/C++中struct,typedef聲明的「過程」問題。

指針是兩個變數,一個是指針本身,一個是指向的對象。
你聲明結構體的時候裡面有個指針,不管指什麼,實例化的時候總能夠開辟出內存來,指針就是4位元組,指針前面的類型在聲明的時候沒有什麼用,只有在解引用的時候才有用,所以聲明的時候指不指向自身沒有區別。但是不能定義該類的對象,類還沒有定義就有了類對象,這不合邏輯,然後也沒法開辟內存。
其他的就是基礎,要聲明某個類型的變數,你得事先告訴編譯器有這個類型。

閱讀全文

與編譯器是如何聲明一個類的相關的資料

熱點內容
如何pdf填充顏色 瀏覽:474
怎麼查看c盤有多少文件夾 瀏覽:682
程序員那麼可愛裡面的男主角 瀏覽:731
編程老師的照片牆 瀏覽:299
函數未定義但是能編譯運行 瀏覽:974
湖南省常德通用壓縮機有限公司 瀏覽:109
伺服器的雙電是什麼意思 瀏覽:614
程序員離開後代碼運行幾天 瀏覽:386
多多樂app是什麼幹嘛的 瀏覽:346
文檔加密授權工具 瀏覽:436
命令與征服將軍閃退 瀏覽:132
vs2019預編譯怎麼設置 瀏覽:780
沈陽中軟python培訓班 瀏覽:493
逆戰文件夾怎麼放 瀏覽:120
怎麼統一刪除文件夾raw文件 瀏覽:121
卡爾曼濾波演算法書籍 瀏覽:769
安卓手機怎麼用愛思助手傳文件進蘋果手機上 瀏覽:844
安卓怎麼下載60秒生存 瀏覽:803
外向式文件夾 瀏覽:240
dospdf 瀏覽:431