仅在某些情况下创建对象,否则返回nullptr [英] Create object only if some condition, otherwise return nullptr
问题描述
仅在应用某些条件的情况下,我才想创建一个对象,否则重新调整nullptr.这就是我在Delphi(2009+)中的处理方式:
I want to create an object only if some conditions are applied, otherwise retun nullptr. This is how I would do it in Delphi (2009+):
function GetGen(n : integer) : Generics.Collections.TList<Integer>;
var
i : integer;
begin
result := nil;
if n > 0 then begin
result := Generics.Collections.TList<Integer>.Create;
for i := 0 to n - 1 do result.Add(i);
end;
end;
procedure TestGenList(n : integer);
var
aInt : integer;
aGen : Generics.Collections.TList<Integer>;
begin
aGen := GetGen(n);
if aGen = nil then begin
WriteLn('No generic created!');
Exit;
end;
WriteLn(Format('Size: %d', [aGen.Count]));
for aInt in aGen do Write(Format('%d ', [aInt]));
aGen.Free; //will clear integers
end;
procedure TestGen
begin
TestGenList(0);
Readln;
TestGenList(5);
Readln;
end.
这就是我在C ++中可以做到的方式:
This is how I could do it in C++ :
unique_ptr<vector<int>> GetUniquePrtVec(int n){
if (n < 1) return(nullptr); //create only if correct input is given
unique_ptr<vector<int>> result (new vector<int>);
for (int i = 0 ; i != n; i++){
result->push_back(i);
}
return(move(result));
}
void TestPtrVec(int n){
unique_ptr<vector<int>> vec = GetUniquePrtVec(n);
if (vec == nullptr){
cout << "No vector created" << endl;
return;
}
cout << endl << vec->size() << endl;
for_each(vec->begin(), vec->end(), [](int n){cout << n << " " << endl;});
vec->clear(); //clear vector
vec.reset(nullptr);
}
void testVec3(){
TestPtrVec(0);
TestPtrVec(5);
}
我的问题是关于正确的成语.你们,经验丰富的C ++程序员(因为我是初学者,只是学习语言),会这样吗?如果没有,那么您将如何做?
My question is about the right idiom. Would you guys, experienced C++ programmers (for I am a beginner, just learning the language), do it this way? If not, then how would you do it?
谢谢.
推荐答案
IMHO(您的示例的最佳方法)将是简单地按值返回 std :: vector
并仅返回一个空如果输入无效,则输入一个.
IMHO, the best way for your example, would be to simply return the std::vector
by value and simply return an empty one if the input is invalid.
std::vector<int> get_vec(int n){
std::vector<int> ret;
for(unsigned i=0; i < n; ++i)
ret.push_back(i);
return ret; // will be empty for (n < 1)
// and will be moved if (n >= 1)
}
您需要学习的一件事:如果您返回局部变量,则无需显式地 std :: move
.只是按价值返回.如果可以进行复制省略,则将这样做(RVO/NRVO).如果由于某种原因不能执行此操作,则它将首先尝试将其移出,然后再进行复制.但是请注意,局部变量的成员也不会自动移动,也就是
One thing you need to learn: You don't need to explicitly std::move
if you return a local variable. Just return by value. If copy elision is possible, it will do that (RVO / NRVO). If it can't for some reason, it'll first try to move it out before copying it. Note however, that a member of a local variable will not be moved automatically, aka
struct object{ std::vector<int> member; };
std::vector<int> foo(){
object o;
// ...
return o.member; // no move, no copy elision, plain old copy
}
现在,您的第二个功能也可以得到改善和减少:
Now, your second function can also be improved and reduced:
void try_vec(int n){
auto vec = get_vec(n); // will elide copy or simply move
for(auto& x : vec) // will not loop if vector is empty
std::cout << x << ' '; // why space and newline?
std::cout << "\n"; // don't use std::endl, it also flushes the stream
}
从您的原始功能开始:
vec->clear(); //clear vector
vec.reset(nullptr);
不需要,这就是智能指针和资源管理容器的全部原因.他们超出范围时会破坏自己的财产.
Is not needed, that's the whole reason for smart pointers and resource managing containers. They will destroy what they own when they go out of scope.
这篇关于仅在某些情况下创建对象,否则返回nullptr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!