正确地返回一个唯一的ptr
Properly return a unique ptr
我正在编写一个String类MyString
(是的,作为作业),并且必须提供一个返回unique_ptr<char[]>
(而不是Vector
)的toCString
方法。不幸的是,我在将指针返回给调用者时失败了:结果总是填充了错误的内容——似乎我在堆栈上创建了指针和/或字符数组。
unique_ptr<char[]> MyString::toCString() const {
char *characters = new char[m_len];
char *thisString = m_string.get();
for (int i = 0; i < m_len; i++) {
characters[i] = *(thisString + m_start + i);
}
const unique_ptr<char[], default_delete<char[]>> &cString = unique_ptr<new char[m_len]>(characters);
return cString;
}
调试时,我总是得到预期的行为。问题仅发生在呼叫者网站上。我的错误在哪里?
我看到已经有了一个公认的答案,但这并不能解决问题。客户端出现问题是因为终止c字符串时不是null。
我不知道m_string是什么类型,所以让我们暂时假设它是std::string。你可以自己翻译实际的方法:
std::unique_ptr<char[]> MyString::toCString() const
{
// get length (in chars) of string
auto nof_chars = m_string.size();
// allocate that many chars +1 for the null terminator.
auto cString = std::unique_ptr<char[]>{new char[nof_chars + 1]};
// efficiently copy the data - compiler will replace memcpy
// with an ultra-fast sequence of instructions in release build
memcpy(cString.get(), m_string.data(), nof_chars * sizeof(char));
// don't forget to null terminate!!
cString[nof_chars] = ' ';
// now allow RVO to return our unique_ptr
return cString;
}
根据Christophe的建议,这里又是一个方法,用std::copy_n写成。请注意,std::copy[_xxx]函数套件都返回一个迭代器,该迭代器寻址最后一次写入之后的一个。我们可以使用它来节省重新计算null终止符的位置。标准图书馆不是很棒吗?
std::unique_ptr<char[]> MyString::toCString() const
{
// get length (in chars) of string
auto nof_chars = m_string.size();
// allocate that many chars +1 for the null terminator.
auto cString = std::unique_ptr<char[]>{new char[nof_chars + 1]};
// efficiently copy the data - and don't forget to null terminate
*std::copy_n(m_string.data(), nof_chars, cString.get()) = ' ';
// now allow RVO to return our unique_ptr
return cString;
}
不要像以前那样创建对unique_ptr的引用。相反,直接返回unique_ptr:move构造函数将处理所有内容:
return unique_ptr<char[], default_delete<char[]>>(characters);
由于您已经编辑了问题,现在您正在使用
unique_ptr<char[]> cString = unique_ptr<char[]>{new char[m_len]};
第一个改进:使用自动
auto cString = unique_ptr<char[]>{new char[m_len]};
第二个改进:你的标签是C+11,但如果你碰巧使用C+14,那么使用std::make_unique
,如下所示:
auto cString = std::make_unique<char[]>(m_len);
此外,正如Scott Meyers所说,如果您使用的是C+11,那么只需自己编写make_unique
函数即可。这并不难,而且非常有用。
http://ideone.com/IIWyT0
template<class T, class... Types>
inline auto make_unique(Types&&... Args) -> typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
{
return (std::unique_ptr<T>(new T(std::forward<Types>(Args)...)));
}
template<class T>
inline auto make_unique(size_t Size) -> typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, std::unique_ptr<T>>::type
{
return (std::unique_ptr<T>(new typename std::remove_extent<T>::type[Size]()));
}
相关文章:
- c++多进程编写一个唯一的文件
- 我需要编写一个程序来读取一个文件,该文件将输出所有唯一的整数,如果已经看到整数,它将被关闭
- 从另一个唯一 ptr 的原始 ptr 创建唯一的 ptr
- 如何在以 256 为基数的唯一 xLen-digit 表示中写一个整数 x?
- 需要在C 中生成一个从00001到99999的唯一5位数字
- 如何在给定任意数量的整数的情况下创建一个唯一键?并使用该键存储,然后从地图中查找
- 尝试创建一个读取.txt文件,显示它,计数唯一单词的程序,并在使用了多少次的情况下显示独特的单词.C
- 如何制作一个采用类型类的唯一指针?(通用)它不让我
- 为什么要在 c++ 中创建一个指向基元类型的唯一指针?
- 如何将唯一指针从一个向量移动到另一个唯一指针向量
- 将 n 个整数组合成一个唯一的表示形式
- 正确地返回一个唯一的ptr
- 为每个对象定义一个唯一的函数
- 需要在数组中找到一个唯一的数字
- 更快的方式,然后我填充一个唯一的整数除了两个值的向量?c++
- 如何将三个整数组合成一个唯一的标记,使标记在c++中保持整数
- 一个唯一的ptr类如何将它的实例指针传递给它的成员对象
- 试图在每次迭代中产生一个唯一的随机数序列
- 可变模板类:每个可变模板参数可以实现一个唯一的成员函数吗
- 如何将两个正整数映射为一个唯一的整数