【问题标题】:Initialising C structures in C++ code在 C++ 代码中初始化 C 结构
【发布时间】:2010-01-03 12:36:28
【问题描述】:

有没有更好的方法在 C++ 代码中初始化 C 结构?

我可以在变量声明点使用初始化列表;但是,如果在编译时不知道所有参数,或者我没有声明本地/全局实例,则这不是很有用,例如:

声明结构的旧 C 代码,也有 API 使用它

typedef struct
{
    int x, y, z;
} MyStruct;

使用 C 库的 C++ 代码

void doSomething(std::vector<MyStruct> &items)
{
    items.push_back(MyStruct(5,rand()%100,items.size()));//doesn't work because there is no such constructor
    items.push_back({5,rand()%100,items.size()});//not allowed either

    //works, but much more to write...
    MyStruct v;
    v.x = 5;
    v.y = rand()%100;
    v.z = items.size();
    items.push_back(v);
}

创建本地实例,然后一次为每个成员设置一个(myStruct.x = 5; 等)真的很痛苦,并且在尝试向容器中添加 20 个不同的项目时有点难以阅读......

【问题讨论】:

  • 您在寻找 C 或 C++ 的解决方案吗?

标签: c++ c initialization structure


【解决方案1】:

如果你不能添加构造函数(这是C++03中最好的解决方案,但你可能与C有兼容性限制),你可以写一个相同效果的函数:

MyStruct makeAMyStruct(int x, int y, int z)
{
    MyStruct result = { x, y, z };
    return result;
}

items.push_back(makeAMyStruct(5,rand()%100,items.size()));

编辑:我现在已经检查过 C++0X 是否为这个精确的问题提供了一些东西:

items.push_back(MyStruct{5,rand()%100,items.size()});

在 g++ 4.4 中可用。

【讨论】:

  • 顺便说一句:为什么不使用初始化列表?
  • "...C++0X 提供了一些东西..." 这个功能是否有一个可以用来搜索更多信息的名称?
【解决方案2】:

您正在寻找 C99 复合文字。示例代码:

struct foo *foo = malloc(sizeof *foo);
*foo = (struct foo){ bar, baz };

【讨论】:

  • 如果编译器 (VC++9) 支持的话,这听起来是个不错的解决方案:(
  • 这一次,实际上不是编译器的错,因为复合文字是 C++ 不支持的 C99 特性;我误读了您的问题,并认为您正在寻找 C 中的解决方案...
  • 参见stackoverflow.com/questions/1705147/… 了解一些解释和 C++0x 语法
  • 向 MS 抱怨他们的 C 编译器是过时的,因为它只支持 20 年前的标准,而不是 10 年前的替代标准。
【解决方案3】:

怎么样:

MyStruct v = {5, rand()%100, items.size()};
items.push_back(v);

【讨论】:

  • 所以要做多件事情就得做v1、v2、v3、v4等,没有办法重用一个本地的?
  • 如果你有 v1、v2、v3 和 v4,你会被困在写出 4 次的东西 - 除非你希望它们具有相同的值,在这种情况下你可以做简单的分配,课程。如果你有 v[0]、v[1]、v[2]、v[3] 和 v[4],那么你可以使用循环。
  • 我对此不是 100% 确定,但我认为:MyStruct vs[2] = {{1, 2, 3}, {2, 3, 4}};会工作
【解决方案4】:

创建一个函数来初始化它,类似于 C++ 构造函数。

【讨论】:

  • (+1) KISS 从各个角度回答。
【解决方案5】:

不清楚你在问什么。在 C++ 中,显而易见的解决方案是给 struct 一个构造函数:

struct MyStruct {
  int x, y, z;
  MyStruct( int ax, int ay, int az ) : x( ax ), y( ay ), z( az ) {}
};

【讨论】:

  • 他正在寻找 C 中的解决方案
  • 那他为什么把它标记为 C++?这就是为什么我说我不清楚。
  • 我的猜测是他的头文件必须保留在 C 中(项目之间共享的遗留代码),但他想要一种在 C++ 中使用结构的便捷方式。
  • 事情是它在一些遗留 C 代码中的结构,所以除非有某种方法可以追溯添加构造函数(即不破坏与 C 库的兼容性,并且最好不编辑c 头文件本身中的声明)?
【解决方案6】:

另一个选择是从结构派生并在那里添加一个构造函数。

struct MyDerivedStruct : public MyStruct
{
    MyDerivedStruct(int xi, int yi, int zi)
    {
        x = xi;
        y = yi;
        z = zi;
    }
}

然后您可以在自己的代码中使用这个派生类型,并在必要时将其传递给 C 库。该语言应注意在适当时隐式转换为MyStruct

作为奖励,您还可以添加其他有用的成员函数,甚至可以包装许多使用这种类型的遗留 C 函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2012-07-16
    相关资源
    最近更新 更多