繁体   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