如何使用自定义类声明数组
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
是聚合);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;
}
};
-或者,如果你不需要它,删除现有的构造函数。
如果类的"空"版本没有意义,则没有好的解决方案在编译时为数组的所有元素提供初始化参数。您可以:
- 有一个构造函数创建一个空版本的类,和一个
init()
函数做真正的初始化 - 使用
vector
,在初始化时创建对象并将它们插入vector
,使用vector::insert
或循环,并且相信在编译时不这样做并不重要。 - 如果对象也不能被复制,你可以使用智能指针的数组/向量指向对象,并在初始化时分配它们。
- 如果你可以使用c++ 11,我认为(?)你可以使用初始化器列表来初始化向量并初始化它(我不确定这是否适用于任何构造函数,或者仅当对象是从另一种类型的单个值创建的)。例如:。
std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" };
"
你只需要添加一个默认构造函数到你的类,看起来像这样:
class name {
public:
string first;
string last;
name() {
}
name(string a, string b){
first = a;
last = b;
}
};
您的class:
class name {
public:
string first;
string last;
name() { } //Default constructor.
name(string a, string b){
first = a;
last = b;
}
};
有一个显式的构造函数,需要两个字符串形参。没有显式编写构造函数的类获得不带参数的默认构造函数。添加显式构造函数会阻止编译器为您生成默认构造函数。
因此,如果您希望创建一个未初始化对象的数组,请为您的类添加一个默认构造函数,以便编译器知道如何在不提供这两个字符串参数的情况下创建它们—参见上面的注释行。
- 在类c++中使用new声明数组
- 为什么不能用常量表达式声明数组?
- 声明数组后我无法添加数组
- 可以使用<size_t>static_const(),std::as_const()或static_cast<const size_t>()来声明数组吗?
- 变量未在此范围内声明 数组线性搜索
- 在类中声明数组. C++
- T D[N] 总是声明数组类型的对象吗?
- 如何使用智能指针在二维上声明数组?
- 声明数组>> int arr[] 时出错;在C++(虽然在 Java 中有效)?
- 在C 类中声明数组数据
- 声明数组时出现 SIGSEGV 错误,而不创建新的 int[size]
- 如何在不初始化常量的情况下声明数组?
- 使用函数在函数中声明数组值
- 以C++声明数组的时间复杂度
- 通过传递数组长度在函数内声明数组
- 通过引用传递数组,而不在函数声明中显式声明数组的大小
- 声明数组和打印[错误?]
- 用内核参数在CUDA内核中声明数组
- 如何在不依赖#Define的情况下转发声明数组大小
- 声明数组已经填充了零