仅在某些情况下创建对象,否则返回nullptr [英] Create object only if some condition, otherwise return nullptr

查看:75
本文介绍了仅在某些情况下创建对象,否则返回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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆