簡體   English   中英

c++ 在構造函數中使用 class 成員作為參數

[英]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的類型可用於構造M1TypeM2Type並獲得與使用從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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM