[英]c++ Using class member as a parameter in constructor
我有一個 class,我需要使用其中一個成員作為構造函數參數來初始化同一 class 的另一個 const 成員。
class A
{
private:
M1Type m1;
const M2Type m2;
public:
A(x) : m1(x), m2(m1){}
};
這是初始化m2的正確方法嗎? 列表初始化中m1的構造完成了嗎?
是的,當它用於初始化m2
並且可以從M2Type
構造M1Type
時,“ m1 的構造完成”,這很好 - 但x
需要A(x)
中的類型。
初始化順序是您在 class 中定義成員變量的順序,而不是您在成員初始化程序列表中使用它們的順序:
M1Type m1;
const M2Type m2;
A(M1Type x) : m2(m1), m1(x) {} // wrong order, but still ok
如果x
的類型可用於構造M1Type
和M2Type
並獲得與使用從x
構造的M2Type
構造M1Type
相同的結果,則不妨使用x
來構造兩者,以免在重組時出現問題稍后的成員變量。 但這並不總是可能的。
例子:
struct M1Type {
explicit M1Type(double) {};
};
struct M2Type {
explicit M2Type(M1Type) {}
};
class A {
public:
M1Type m1;
const M2Type m2;
public:
// error: no matching function for call to 'M2Type::M2Type(double&)':
// A(double x) : m1(x), m2(x) {}
A(double x) : m1(x), m2(m1) {} // OK
};
成員按照它們在 class 定義中出現的順序進行初始化(與初始化列表中的順序無關)。 因此,第一個m1
被初始化,您可以使用它的值來初始化m2
。
這段代碼
class A
{
private:
M1Type m1;
const M2Type m2;
public:
A(int x) : m1(x), m2(m1){}
};
很好(除了缺少x
類型)。 不過,如果可能的話,我寧願這樣寫:
class A
{
private:
M1Type m1;
const M2Type m2;
public:
A(int x) : m1(x), m2(x){}
};
因為現在正確性不取決於成員的順序。 重構時可能會發生變化。 當初始化列表中的順序不同時,編譯器通常會發出警告,但是無論成員的順序如何,您都可以依賴正確的代碼,而不是依賴警告。
請注意,編譯器不一定會警告此代碼(交換成員的順序):
class A
{
private:
const M2Type m2;
M1Type m1;
public:
A(int x) : m2(m1),m1(x) {} // !! most likely UB !!
};
但如果M2Type
的構造函數使用m1
的值,它具有未定義的行為,因為m1
未初始化使用。 因此,當成員的初始化相互依賴時,應該小心。
假設 M2Type 具有接受 M1Type 參數的構造函數應該可以工作。
PS: A(x) - 應該指定 x 的類型。
執行下面的代碼可以確保它有效:
#include <iostream>
class M1Type
{
public:
int iField;
M1Type(int x): iField{x}
{
std::cout << "M1Type(int x)" << iField << std::endl;
}
};
class M2Type
{
public:
int iField;
M2Type(M1Type m1) : iField{ m1.iField + 500 }
{
std::cout << "M2Type(M1Type m1)" << iField << std::endl;
}
};
class A
{
private:
M1Type m1;
const M2Type m2;
public:
A(int x) : m1(x), m2(m1)
{
std::cout << "A(int x): M1Type: " << m1.iField << "; M2Type: " << m2.iField << std::endl;
}
};
int main()
{
A objA(73);
}
控制台 output 將是:
M1Type(int x)73
M2Type(M1Type m1)573
A(int x): M1Type: 73; M2Type: 573
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.