[英]How do I call the base class constructor?
最近,我用 Java 做了很多編程。 在那里,您使用super().
調用繼承自的類super().
(你們可能都知道。)
現在我有一個 C++ 類,它有一個帶有一些參數的默認構造函數。 例子:
class BaseClass {
public:
BaseClass(char *name); ....
如果我繼承了這個類,它會警告我沒有合適的默認構造函數可用。 那么,在 C++ 中是否有像super()
這樣的東西,還是我必須定義一個函數來初始化所有變量?
您可以在子類的構造函數的初始化列表中執行此操作。
class Foo : public BaseClass {
public:
Foo() : BaseClass("asdf") {}
};
在初始化任何成員之前,必須在那里調用帶有參數的基類構造函數。
在頭文件中定義一個基類:
class BaseClass {
public:
BaseClass(params);
};
然后將派生類定義為繼承 BaseClass:
class DerivedClass : public BaseClass {
public:
DerivedClass(params);
};
在源文件中定義 BaseClass 構造函數:
BaseClass::BaseClass(params)
{
//Perform BaseClass initialization
}
默認情況下,派生構造函數只調用沒有參數的默認基構造函數; 所以在這個例子中,基類的構造並不時自動派生構造函數被調用調用,但它可以簡單地用冒號之后加入基類的構造的語法來實現( :
)。 定義一個派生構造函數,自動調用其基構造函數:
DerivedClass::DerivedClass(params) : BaseClass(params)
{
//This occurs AFTER BaseClass(params) is called first and can
//perform additional initialization for the derived class
}
BaseClass
構造函數在DerivedClass
構造函數之前被調用,如果需要,可以將相同/不同的參數params
轉發到基類。 這可以嵌套用於更深的派生類。 派生構造函數必須只調用一個基構造函數。 析構函數以調用構造函數的相反順序自動調用。
編輯:如果您從任何virtual
類繼承,則此規則有一個例外,通常是為了實現多重繼承或菱形繼承。 那么你必須顯式調用所有virtual
基類的基構造函數並顯式傳遞參數,否則它只會調用它們的默認構造函數而沒有任何參數。 請參閱: 虛擬繼承 - 跳過構造函數
您必須使用初始化程序:
class DerivedClass : public BaseClass
{
public:
DerivedClass()
: BaseClass(<insert arguments here>)
{
}
};
這也是您構造沒有構造函數(或您想要初始化)的類成員的方式。 任何未提及的成員將被默認初始化。 例如:
class DerivedClass : public BaseClass
{
public:
DerivedClass()
: BaseClass(<insert arguments here>)
, nc(<insert arguments here>)
//di will be default initialized.
{
}
private:
NeedsConstructor nc;
CanBeDefaultInit di;
};
指定成員的順序無關緊要(盡管構造函數必須在前),但它們的構造順序是聲明順序。 所以nc
總是在di
之前構造。
關於super的替代品; 在大多數情況下,您會在派生類的初始化列表中使用基類,或者在其他地方工作並且派生類重新定義數據成員時使用Base::someData
語法。
struct Base
{
Base(char* name) { }
virtual ~Base();
int d;
};
struct Derived : Base
{
Derived() : Base("someString") { }
int d;
void foo() { d = Base::d; }
};
在初始化列表中使用基類的名稱。 初始化列表出現在方法體之前的構造函數簽名之后,可用於初始化基類和成員。
class Base
{
public:
Base(char* name)
{
// ...
}
};
class Derived : Base
{
public:
Derived()
: Base("hello")
{
// ...
}
};
或者,有些人使用的模式是自己定義“超級”或“基礎”。 也許一些喜歡這種技術的人是轉向 C++ 的 Java 開發人員。
class Derived : Base
{
public:
typedef Base super;
Derived()
: super("hello")
{
// ...
}
};
C++ 中沒有 super() 。 您必須按名稱顯式調用 Base Constructor。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.