1023 Have Fun with Numbers (20)(vector<int> di,di读取string里的数字)

本文介绍了一个简单的C++程序,用于验证信用卡号的有效性。通过读取输入的信用卡号,程序会进行Luhn算法检查,并判断该卡号是否有效。此外,程序还实现了将处理后的数字按原序输出的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include<vector>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std;

class CA
{
public:
 enum{N=21};
 void run();
private:
 vector<int> di,di2,diout;
};

void CA::run()
{
 string s;
 getline(cin,s);
 int i,flag=0;
 for(i=s.size()-1;i>=0;i--)
 {
  di.push_back(s[i]-'0');
  di2.push_back((flag+(s[i]-'0')*2)%10);
  flag=(flag+(s[i]-'0')*2)/10;
 }
 if(flag==1)
  di2.push_back(flag);
 diout=di2;
 sort(di.begin(),di.end());
 sort(di2.begin(),di2.end());
 if(di==di2)
  printf("Yes\n");
 else
  printf("No\n");
 for(i=diout.size()-1;i>=0;i--)
 {
  printf("%d",diout[i]);
 }
}

int main()
{
 //freopen("text.txt","r",stdin);
 CA *a=new CA;
 a->run();
 return 0;
}

<think>嗯,用户的问题是关于C++中如何正确地将unique_ptr存入vector的。具体来说,他们比较了使用push_back配合make_unique和直接传递Fun2()的结果,以及emplace_back的使用情况。首先,我需要回忆unique_ptr的所有权语义,因为unique_ptr不能被复制,只能移动。 用户提供的代码示例中,vec.push_back(make_unique<int>(Fun())),这Fun()返回的是一个int*,所以make_unique<int>(Fun())会创建一个新的unique_ptr,接管这个指针的所有权。而Fun2()返回的是一个unique_ptr<int>,所以直接使用push_back(Fun2())时,需要移动这个指针,因为push_back的参数需要是一个右值引用,所以应该没问题,但可能需要使用std::move,不过如果Fun2()返回的是临时对象,那么自动会成为右值,所以可能不需要显式移动。 接下来,用户提到使用emplace_back(Fun())的情况。这的问题在于,emplace_back会直接构造元素,但Fun()返回的是int*,而vector的元素类型是unique_ptr<int>。如果直接传递原始指针,emplace_back可能会构造一个unique_ptr,接管该指针的所有权,但需要确保没有其他地方管理这个指针,否则会导致双重释放。然而,这可能存在一个问题,因为emplace_back的参数会被转发给unique_ptr的构造函数。unique_ptr的构造函数接受一个指针,但要求是显式的,所以可能需要使用emplace_back(new int(...)),但用户这用的是Fun(),它返回int*。不过,如果直接传递Fun()返回的指针给emplace_back,是否能正确构造unique_ptr呢?因为unique_ptr的构造函数是explicit的,所以emplace_back(Fun())可能无法正确推导参数类型,导致编译错误。例如,emplace_back需要一个Args&&...,而这传递的是int*,所以unique_ptr<int>的构造函数需要显式调用,所以可能需要emplace_back(new int(...))或者更明确的构造方式。 然后,用户询问哪个更好。比较push_back(make_unique(...))和push_back(Fun2()),后者可能更高效,因为它避免了make_unique的额外步骤,直接移动临时对象。而前者需要先创建unique_ptr,然后移动到vector中,但两者可能差别不大。不过,使用Fun2()直接返回unique_ptr更符合资源管理的意图,避免潜在的内存泄漏,比如如果make_unique之前发生异常,但这种情况在当前的例子中可能不存在。 对于emplace_back的情况,如果直接传递原始指针,可能存在风险,因为如果emplace_back在构造unique_ptr<int>时抛出异常,会导致内存泄漏,因为原始指针没有被管理。而使用make_unique的话,即使在构造时发生异常,资源也会被正确释放。因此,使用emplace_back(Fun())可能不安全,而应该使用emplace_back(make_unique<int>(Fun())),或者更推荐使用push_back(make_unique<int>(Fun())),这样更安全。 总结的话,用户需要明确各个方法的区别:push_back需要移动或构造临时对象,而emplace_back可以直接构造,但传递参数时要注意正确性和安全性。直接传递原始指针给emplace_back可能不安全,建议使用make_unique来确保异常安全。同时,Fun2()返回unique_ptr的情况更优,因为直接移动,无需额外步骤。</think>让我们逐步析这两种方式的区别及最佳实践: 1. **`vec.push_back(make_unique<int>(Fun()))`** - ✅ 优点:明确的所有权转移 - `Fun()`返回的原始指针立即被`make_unique`接管,避免内存泄漏 - 完全符合RAII原则,异常安全 - ❌ 缺点:需要显式构造`unique_ptr` - 多一次智能指针构造的开销(通常可忽略) 2. **`vec.push_back(Fun2())`** - ✅ 更优选择:直接移动语义 - `Fun2()`直接返回`unique_ptr`,利用移动构造 - 减少一次临时对象的构造(更高效) - 代码更简洁直观 3. **`vec.emplace_back(Fun())`** - ⚠️ 危险操作:不推荐直接使用 - `emplace_back`会尝试用原始指针直接构造`unique_ptr` - 虽然语法合法,但会导致两个问题: 1. 所有权不明确:原始指针可能被其他代码误用 2. 异常不安全:若`emplace_back`在插入时抛出异常,会导致内存泄漏 - ✅ 改进方案:应使用`emplace_back(make_unique<int>(Fun()))` **最终建议:** 1. 优先使用`vec.push_back(Fun2())` - 效率最高且最安全 - 符合现代C++的移动语义设计 2. 当必须处理原始指针时,使用: ```cpp vec.push_back(make_unique<int>(Fun())); // 或 vec.emplace_back(make_unique<int>(Fun())); ``` 3. 绝对避免直接传递原始指针到容器中 **补充说明:** - `push_back()`与`emplace_back()`的选择: - 当参数类型与容器元素类型完全匹配时,优先用`emplace_back` - 需要类型转换时,`push_back`更安全明确 - 性能对比示例: ```cpp // 最优:移动现成的unique_ptr vec.push_back(Fun2()); // 1次移动构造 // 次优:构造+移动 vec.push_back(make_unique(...));// 1次构造+1次移动 // 最差:危险操作 vec.emplace_back(raw_ptr); // 潜在内存风险 ``` 结论:在保证安全性的前提下,`vec.push_back(Fun2())`是最优方案,既高效又明确表达了所有权转移。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值