[英]Confused about C++ class usage
以下是讓我對 class 的用法有些困惑的代碼。
template <int dim>
class FEM
{
public:
FEM (unsigned int order,unsigned int problem);
~FEM();
...
FESystem<dim> fe;
DoFHandler<dim> dof_handler;
...
}
template <int dim>
FEM<dim>::FEM(unsigned int order,unsigned int problem)
:
fe (FE_Q<dim>(order), dim),
dof_handler (triangulation)
{
...
}
這里的“FESystem”、“DoFHandler”和“FE_Q”是頭文件中的一些預定義類。 我對這段代碼有幾個問題:
(1)為什么構造函數“fe”和“dof_handler”在類“FE”本身之外聲明,是否有可能在第一個括號內,即在“FE”類定義內聲明它們?
(2)代碼中的雙冒號和冒號“ :: ”和“ : ”分別是什么意思? 為什么在這里使用它們? 冒號“:”是否表示繼承?
template <int dim>
FEM<dim>::FEM(unsigned int order,unsigned int problem)
:
fe (FE_Q<dim>(order), dim),
dof_handler (triangulation){...}
我是 C++ 新手。 誰能給我一些幫助? 太欣賞了!
雙冒號用於指定您正在為特定類實現函數。 在本例中,它是 FEM 類的構造函數的實現。 如果 FEM 有一個方法 DoIt(),則實現可能如下所示:
template<int dim>
int FEM<dim>::DoIt() { return 1; }
如果要將參數直接傳遞給成員變量的構造函數,則單冒號“:”與構造函數一起使用。 所以在上面的代碼中,FEM 的構造函數正在將參數傳遞給它的成員fe
。 FESystem 必須有一個構造函數,它接受一個 FE_Q << dim >> 和一個 int 作為參數。 它也在向 DoFHandler 傳遞一些東西,但不清楚代碼中的triangulation
是什么。 這看起來不會編譯。
(1)為什么構造函數“fe”和“dof_handler”在類“FE”本身之外聲明,是否有可能在第一個括號內,即在“FE”類定義內聲明它們?
是的,對於模板化類,它們可以位於“FE”模板類定義的內部或外部。 有些人更喜歡它們的可讀性,在那里他們可以看到每個可用功能的列表,而不必向下滾動太多。
但是,對於常規的非模板化類,請將您的類外實現放在相應的源 ( .cpp
) 文件中,而不是在類下方或類中。 原因是,包含您的頭文件的所有其他類都將一遍又一遍地編譯相同的實現,這將減慢您的構建速度並生成大量二進制文件。 對於模板化類,您別無選擇。 它們必須由每個翻譯單元編譯,因為模板化將由您的編譯器生成代碼。
(2)代碼中的雙冒號和冒號“::”和“:”分別是什么意思? 為什么在這里使用它們? 冒號“:”是否表示繼承?
雙冒號是你的范圍。 它可以是命名空間或類名。 這使得可以從兩個不同的類中命名完全相同的 2 個函數而不會發生名稱沖突。 它對於覆蓋非常有用。
例如,您可以在標題中包含此內容:
class A
{
public:
virtual foo(int a);
};
class B : public A
{
public:
virtual foo(int a);
};
並將其放在您的源 ( .cpp
) 文件中:
A::foo(int a) {
printf("Hello World from A::foo(%s)\n", a);
}
B::foo(int a) {
A::foo(a); // calling the super class's foo(int)
printf("Hello World from B::foo(%s)\n", a);
}
如果我們沒有作用域,我們將無法區分這兩個函數。 在 Java 或 C# 中,這已被簡化為一個點。
這種特殊情況下的單冒號是 C++ 構造函數的一個非常特殊的特性。 只有構造函數可以做到這一點。 這稱為“初始化程序”,它們是一種巧妙的小優化,可用於比在構造函數范圍內手動設置成員變量的默認值更快。
例如,如果你在這里有這個類:
class A
{
public:
A(); // constructor
int a;
float b;
};
您可能希望在.cpp
源文件中像這樣編寫構造函數:
A::A() {
a = 0;
b = 0.0;
}
但是,通過初始化,您可以這樣編寫:
A::A() :
a(0),
b(0.0)
{
}
據說它們可以更快地初始化您的內存,只要您以與它們在標頭中聲明的順序相同的順序初始化它們。 在這個特殊的例子,如果你初始化b
前a
,優化將無法正常工作。
C++ 一開始可能很難理解,但它是一種非常強大的語言,學習起來真的很有趣。
C++ 中的類方法通常在類定義之外定義。 這與 Java、Python 等不同。它有一個很好的理由:類的定義只包含其方法的原型,即所謂的聲明。 這是程序其他部分了解特定類的外觀所需的所有信息。 類定義保存在頭文件中。 並且這些頭文件需要包含在使用該類的每個源代碼中。
方法的實際實現通常保存在單獨的文件中。 因此,類名和它前面的雙冒號來標識它們所屬的類。
頭文件中的源代碼將與使用這些類定義的每一段代碼一起編譯。 方法背后的實際程序可以單獨編譯,並在鏈接階段添加。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.