避免复制粘贴代码初始化Struct中的一系列SDL_Rect

时间:2012-02-13 12:57:27

标签: c++ boost sdl

我有一个结构用于定义2D引擎中的特征图形。在那里,有一系列SDL_Rects被称为“middle,left_edge,top_left_corner”等。在我的代码的一部分中,我将它们从脚本引擎/命令行中的一系列参数类型初始化,存储为向量std :: strings。

作为一种风格问题,并避免因重复而导致的愚蠢错误(并且必须纠正任何错误9次),有没有办法清理这些代码?或者这是否合理?

//RectZeroes is just an SDL_Rect of {0,0,0,0} to ensure that it is initialised

        SDL_Rect middle = RectZeroes;
        if (args.size() >= 6 ) 
        {
            middle.x = boost::lexical_cast<int>(args[3]); 
            middle.y = boost::lexical_cast<int>(args[4]);
            middle.w = boost::lexical_cast<int>(args[5]);
            middle.h = boost::lexical_cast<int>(args[6]);
        }

        SDL_Rect left_edge = RectZeroes;
        if (args.size() >= 10 ) 
        {
            left_edge.x = boost::lexical_cast<int>(args[7]); 
            left_edge.y = boost::lexical_cast<int>(args[8]);
            left_edge.w = boost::lexical_cast<int>(args[9]);
            left_edge.h = boost::lexical_cast<int>(args[10]);
        }
//And so on

1 个答案:

答案 0 :(得分:2)

我同意这不是一个令人愉快的代码。为避免重复,请在编程中始终如此: encapsulate - 在这种情况下,封装结构并为其提供正确的构造函数,并在boost::lexical_cast<int>(x)周围编写一个瘦包装。

或者,如果您想避免包装SDL_Rect,请编写初始化函数:

template <typename TString>
int parse_int(TString const& value) { return boost::lexical_cast<int>(value); }

void init_sdl_rect_from_args(
    SDL_Rect& rect, std::vector<std::string> const& args, unsigned offset)
{
    rect.x = parse_int(args[offset + 0]);
    rect.y = parse_int(args[offset + 1]);
    rect.w = parse_int(args[offset + 2]);
    rect.h = parse_int(args[offset + 3]);
}

然后:

SDL_Rect middle = RectZeroes;
if (args.size() >= 6)
    init_sdl_rect_from_args(middle, args, 3);

SDL_Rect left_edge = RectZeroes;
if (args.size() >= 10)
    init_sdl_rect_from_args(left_edge, args, 7);

更好的是,让初始化返回构造的结构。这使得使用起来更方便(即,在初始化器中):

SDL_Rect rect_from_args(std::vector<std::string> const& args, unsigned offset) {
    SDL_Rect rect;
    rect.x = parse_int(args[offset + 0]);
    rect.y = parse_int(args[offset + 1]);
    rect.w = parse_int(args[offset + 2]);
    rect.h = parse_int(args[offset + 3]);
    return rect;
}

SDL_Rect middle = (args.size() >= 6) ? rect_from_args(args, 3) : RectZeroes;
SDL_Rect left_edge = (args.size() >= 10) ? rect_from_args(args, 7) : RectZeroes;