簡體   English   中英

如何使用自定義類聲明數組?

[英]How do I declare an array with a custom class?

我試圖用自定義類聲明一個數組。 當我向類中添加構造函數時,編譯器會抱怨“沒有匹配的構造函數來初始化name [3]”。

這是我的程序:

#include <iostream>

using namespace std;

class name {
  public:
    string first;
    string last;

  name(string a, string b){
    first = a;
    last = b;
  }
};

int main (int argc, const char * argv[])
{

  const int howManyNames = 3;

  name someName[howManyNames];

  return 0;
}

我可以做些什么來做這個,我做錯了什么?

您必須提供一個默認的構造函數。 在使用它的同時,還要修復其他構造函數:

class Name
{
public:
  Name() { }
  Name(string const & f, string const & l) : first(f), last(l) { }
  //...
};

或者,您必須提供初始化程序:

Name arr[3] { { "John", "Doe" }, { "Jane", "Smith" }, { "", "" } };

從概念上講,后者是更可取的,因為您的類沒有理由應該具有“默認”狀態的概念。 在這種情況下,您只需要為數組的每個元素提供適當的初始化程序。

C ++中的對象永遠不能處於未定義狀態。 如果考慮到這一點,一切應該變得非常清楚。


一種替代方法是使用動態容器,盡管這與您要求的有所不同:

std::vector<Name> arr;
arr.reserve(3);  // morally "an uninitialized array", though it really isn't

arr.emplace_back("John", "Doe");
arr.emplace_back("Jane", "Smith");
arr.emplace_back("", "");

std::vector<Name> brr { { "ab", "cd" }, { "de", "fg" } }; // yet another way

要默認初始化T的數組, T必須是默認可構造的。 通常,編譯器免費提供默認的構造函數。 但是,由於您自己聲明了構造函數,因此編譯器不會生成默認構造函數。

您的選擇:

  • 如果可以的話,在名稱中添加默認構造函數(我認為不是,但是我不知道問題域);
  • 在聲明時初始化數組的所有元素(您可以執行此操作,因為name是一個聚合);

      name someName[4] = { { "Arthur", "Dent" }, { "Ford", "Prefect" }, { "Tricia", "McMillan" }, { "Zaphod", "Beeblebrox" } }; 
  • 請改用std::vector ,並僅在構造它們時添加元素。

您需要一個無參數的構造函數才能創建您的類的實例。 您當前的構造函數需要兩個輸入字符串參數。

通常,如果沒有其他構造函數聲明,則C ++暗示具有這樣的構造函數(=默認無參數構造函數)。 通過使用兩個參數聲明第一個構造函數,您將覆蓋此默認行為,現在必須顯式聲明此構造函數。

這是工作代碼:

#include <iostream> 
#include <string>  // <-- you need this if you want to use string type

using namespace std; 

class name { 
  public: 
    string first; 
    string last; 

  name(string a, string b){ 
    first = a; 
    last = b; 

  }

  name ()  // <-- this is your explicit parameterless constructor
  {}

}; 

int main (int argc, const char * argv[]) 
{ 

  const int howManyNames = 3; 

  name someName[howManyNames]; 

  return 0; 
}

(順便說一句,您需要包括以使代碼可編譯。)

另一種方法是在聲明時顯式初始化實例

  name someName[howManyNames] = { {"Ivan", "The Terrible"}, {"Catherine", "The Great"} };

您只需要在類中添加默認構造函數即可,如下所示:

class name {
  public:
    string first;
    string last;

  name() {
  }

  name(string a, string b){
    first = a;
    last = b;
  }
};

你的班:

class name {
  public:
    string first;
    string last;

  name() { }  //Default constructor.

  name(string a, string b){
    first = a;
    last = b;
  }
};

有一個需要兩個字符串參數的顯式構造函數。 沒有明確編寫構造函數的類將獲得不帶參數的默認構造函數。 添加顯式構造函數會阻止編譯器為您生成該默認構造函數。

因此,如果您希望創建未初始化對象的數組,請向您的類添加默認構造函數,以便編譯器知道如何在不提供這兩個字符串參數的情況下創建它們-請參見上面的注釋行。

為了創建對象數組,這些對象需要一個不帶任何參數的構造函數(這將創建該對象的默認形式,例如,兩個字符串均為空)。 這就是錯誤消息的含義。 編譯器會自動生成一個構造函數,該構造函數將創建一個空對象, 除非存在其他構造函數。

如果有必要將數組元素創建為空(在這種情況下,成員獲取其默認值,在這種情況下,則為空字符串),則應該:

-寫一個空的構造函數:

class name {
  public:
    string first;
    string last;

  name() { }
  name(string a, string b){
    first = a;
    last = b;
  }
};

-或者,如果不需要它,請刪除現有的構造函數。

如果您的類的“空”版本沒有意義,那么沒有很好的解決方案在編譯時為數組的所有元素提供初始化參數。 您可以:

  • 讓構造函數始終創建一個空版本的類,並使用一個init()函數進行真正的初始化
  • 使用vector ,並在初始化時創建對象,然后使用vector::insert或循環將其插入到vector ,並相信在編譯時不執行操作並不重要。
  • 如果對象也不能被復制,則可以使用指向對象的智能指針的數組/向量,並在初始化時分配它們。
  • 如果可以使用C ++ 11,我認為(?)可以使用初始化程序列表初始化向量並將其初始化(我不確定該向量是否適用於任何構造函數,或者僅當對象是由另一個構造函數的單個值創建時才能確定)類型)。 例如:。
  std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" }; 

`

暫無
暫無

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

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