簡體   English   中英

在類構造函數中初始化成員

[英]Initializing a member in class constructor

有人可以解釋為什么我不能像在成員初始化列表中那樣在構造函數的主體中初始化變量。

class MyClass
{
  public:
    MyClass();
    virtual ~MyClass(void);
  private:
    std::string test;
};

MyClass::MyClass()
: test("asdf")  <-- Case 1: This is OK
{
    test("asdf");   <-- Case 2: This is not
}

我問我有一個第三方類,我需要通過將某些變量傳遞到其構造函數中來使用和初始化。 如果我像上面的情況1一樣使用它,但是不象情況2那樣使用,那很好。

語法在在成員初始化列表中構造對象和在構造函數的主體中為其分配值之間有所不同。

在初始化列表中,它就是您所擁有的。

MyClass::MyClass()
:test("abcd")
{
  //...
}

在主體中,您可以使用賦值語法

test = "abcd"; 

語法test("asdf"); 被解析為一個稱為test的函數,該函數的參數為"abcd"

必須記住,如果成員沒有默認構造函數,則初始化列表是正確構造成員的唯一位置。 構造函數的主體運行后,所有成員都已以某種方式構造或初始化。 如果可能的話,它們可以被分配給(例如,不適用於引用和const成員等),但是不能重構。

你不能初始化在構造函數體內的變量,因為構造的身體的所有基類后運行和成員已經在成員初始化列表初始化。 它們是隱式默認初始化的,因為您沒有列出它們是不相關的。

因此,在體內, test("asdf"); 嘗試在test上調用operator() ,但失敗。 使用賦值( test = "asdf"; )可以更改其值,或者最好在成員初始化列表中直接對其進行初始化。

您可以通過以下方式在構造函數中初始化變量:

class MyClass
{
public:
    MyClass();
    virtual ~MyClass(void);
private:
    std::string test;
};

方法1:

MyClass::MyClass() : test("asdf")
{
}

方式2:

MyClass::MyClass()
{
    test = "asdf";
}

test(“ asdf”)是一個函數調用,您不能調用這樣的字符串。 初始化列表(“情況1”)是一種特殊情況。

在構造函數主體中,只需使用賦值

test="asdf".

在這種情況下,首先字符串測試是默認構造的(變為空),然后構造新的字符串並將其分配給成員test。

您無法在構造函數主體中初始化成員,因為該成員已在此時進行了初始化,並且語法反映了這一事實。 這已經得到了回答,但是我想指出另一件事-不正確地使用術語可能會導致代碼不正確。 因此有人說“您可以通過賦值在構造函數主體中初始化”。 為什么會這樣呢? 讓我們看一下這個例子:

struct foo {
    int i = 0;
    int &r = i;

    foo() {}
    foo( int &ref );
};

如果要調用ctor,則希望r指向與ref相同的對象:

foo::foo( int &ref ) : r( ref )
{
}

現在,如果您嘗試通過賦值“初始化”將會發生什么:

foo::foo( int &ref )
{
    r = ref;
}

因此,現在不再將int引用r指向與ref相同的int ,而是將值分配給成員i 這可能導致難以發現錯誤,並且士氣高漲:“術語在編程中很重要,您不應該隨意使用它”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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