【发布时间】:2015-03-30 12:40:39
【问题描述】:
我有一个如下所示的课程:
class PasswordCategory
{
public:
PasswordCategory(const std::string&);
~PasswordCategory();
PasswordCategory() = delete;
...
}
这会导致与分配器相关的编译器错误:
错误 C2280:'PasswordCategory::PasswordCategory(void)':正在尝试 引用已删除的函数
文件:xmemory0:577
IDE 是 VS 2013 社区。p>
我假设发生这种情况是因为我在其他地方使用了这些类别的向量。
std::vector<PasswordCategory> m_categories;
我只使用 emplace_back(string) 将元素插入其中,但是,PasswordCategory 的默认分配器似乎正在尝试使用 PasswordCategory 的默认构造函数,但由于它已被删除,因此会引发错误。
如果我提供默认构造函数,一切正常,但我想知道如何在没有默认构造函数的情况下缓解这个问题?
我想到了以下解决方案:
- 为构建我的类的类提供自定义分配器。但是,这并不能解决我希望我的字符串参数是非可选的问题。
- 提供默认构造函数,该构造函数只使用一些参数调用我的另一个构造函数。这也没有解决这个参数是非可选的并且不应该被默认的问题。
- 使用引用或指针向量代替值向量。这似乎是最合理的解决方案,但它引入了手动管理内存的需要,除非我们使用 unique_ptr 或类似的东西。
我想知道是否可以以某种方式禁止我的类的无 arg 构造,同时仍然能够按值在标准容器中使用它?
感谢任何答案和见解,提前致谢。
附:这是我的一个小项目,为了更好地理解 C++,我试图避免大多数常见的陷阱,并使一切尽可能可靠,这样当我要从事更大的项目时,我会更容易避免这些常见的陷阱。我尝试以不同的方式提出问题,但没有找到我的问题的答案,所以我问自己的问题。
【问题讨论】:
-
你能告诉我们你对向量做了什么导致错误吗?如果实现符合 C++11/14,它应该可以工作,只要您不做任何特别需要默认构造函数的事情(例如,使用单个参数调用
resize)。定义一个空向量,并使用适当的构造函数参数调用emplace_back,应该没问题。 -
啊,这很好奇。在阅读了您的评论后,我实际上设法找到了罪魁祸首。我正在使用 0 参数初始化我的向量:
PasswordManager::PasswordManager() : m_categories(0) {}在使其成为m_categories()之后,代码编译。我认为初始化大小为 0 的向量不会导致默认分配器的实例化。事实上,我认为它会更好,因为它更冗长,并且清楚地表明向量开始时是空的。原来我错了。 -
您告诉向量使用 N 个默认构造元素填充自身,这采用需要您的类型的默认构造函数的代码路径(即使 N 的运行时值为 0)。默认构造你说你希望它为空的向量,这不需要你的类型的任何构造函数。
-
确实,该构造函数包含用于默认初始化元素的代码 - 因为这是它指定要做的事情 - 所以无论该代码是否实际执行都是错误的。
-
注:您实际上不需要删除默认构造函数,
PasswordCategory(const std::string&)构造函数的存在意味着无论如何都没有默认构造函数。
标签: c++ oop constructor stl allocator