初始化派生类中基于 C 的 API 提供的基于 C 的类型定义结构?
Initialize C-based typedef'd structure provided by C-Based API in derived class?
我有一个OVERLAPPED
,我试图把在一个已知的良好状态。OVERLAPPED
是一个由Win32 API提供的Windows类型定义的结构。我不能改变它。
#pragma push_macro ("WIN32_LEAN_AND MEAN")
#pragma push_macro ("NOMINMAX")
#define WIN32_LEAN_AND MEAN
#define NOMINMAX
#include <windows.h>
struct OverlappedIo : public OVERLAPPED
{
explicit OverlappedIo()
: Internal(0), InternalHigh(0), Offset(0), OffsetHigh(0)
, Pointer(NULL), hEvent(hEvent) { }
...
};
#pragma pop_macro ("NOMINMAX")
#pragma pop_macro ("WIN32_LEAN_AND MEAN")
在MinGW下,它会导致(它可能在本地Win32下有问题;我还没有开始测试平台):
g++ -DNDEBUG -g -O2 -march=native -pipe -c network.cpp
In file included from network.cpp:4:0:
network.h: In constructor 'OverlappedIo::OverlappedIo()':
network.h:244:5: error: class 'OverlappedIo' does not have any field n
amed 'Internal'
: Internal(0), InternalHigh(0), Offset(0), OffsetHigh(0)
^
...
我也尝试了_OVERLAPPED
与相同的结果。当我试图提供缺失的构造函数来执行c++初始化时(我没有期望这能工作,但值得一试):
//! OVERLAPPED I/O
OVERLAPPED::OVERLAPPED()
: Internal(0), InternalHigh(0), Offset(0), OffsetHigh(0), hEvent(NULL) { }
结果是:
In file included from network.cpp:4:0:
network.h:24:24: error: ISO C++ forbids declaration of 'OVERLAPPED' with no type
[-fpermissive]
OVERLAPPED::OVERLAPPED()
^
在c++ 11中,我相信我可以用大括号初始化。但是我不清楚如何在c++ 03中实现它。还要注意,这是一个简化的例子,真正的类要复杂得多,它试图提供更强的异常安全性。由于更强的异常安全性,我想初始化字段,而不是对它们进行memset
或赋值。(对于"initialize"answers"assign"这两个词,我很抱歉)。
是否可以从C中初始化类型定义的结构?
如果是,如何在c++ 03中初始化结构体的字段?
相关的,这是<windows.h>
的结构体:
typedef struct _OVERLAPPED {
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
union {
struct {
DWORD Offset;
DWORD OffsetHigh;
} DUMMYSTRUCTNAME;
PVOID Pointer;
} DUMMYUNIONNAME;
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
c++结构体的成员是否默认初始化为0 ?以及在类构造函数中初始化结构的正确方法。它也与类型名后面的括号与new有区别吗?(我试图避免愚蠢的规则,只是把一个对象放在一个已知的良好状态)。
我不愿意以这种方式处理问题:如果OVERLAPPED以任何方式更改,您的代码都可能无效。如果您希望所有成员都被初始化,那么将来向OVERLAPPED添加的任何成员都可能给程序引入未定义行为。
另外,请注意OVERLAPPED可能不是多态类型,因此在程序开发时可能容易出现内存泄漏。
考虑使用类的OVERLAPPED成员变量,并在构造函数中通过调用memset
将结构初始化为0。
OVERLAPPED
是由pod组成的结构,试图假装它不是毫无意义的。在我看来,使用memset
:
struct OverlappedIo : public OVERLAPPED
{
OverlappedIo(HANDLE e = 0)
{
memset(this, 0, sizeof(OVERLAPPED));
hEvent = e;
}
};
成员Internal
和其他成员是从基类继承的,继承的成员不能在派生类的初始化列表中初始化。
从逻辑上讲,基类的成员在派生类的成员开始初始化时就已经构造好了(并初始化了1)。
<一口> 1。虽然在这种情况下,类型是内置类型,不会初始化为任何合理的值,除非您显式地将它们初始化为。所谓的内置类型的默认初始化意味着未初始化的。因此,在派生类构造函数体中,您可以为赋予合理的值。一口>
这将在c++ 03中对所有内容进行零初始化(但不包括c++ 98):
OVERLAPPED x = OVERLAPPED();
我不确定你是否真的有一个很好的理由想要派生,或者如果这只是为了初始化,但是如果你这样做了:
struct OverlappedIo: OVERLAPPED
{
OverlappedIo(): OVERLAPPED() {}
OverlappedIo(HANDLE h): OVERLAPPED() { hEvent = h; }
};
当然,添加构造函数意味着不能再使用聚合初始化。
在c++ 11中,当然你可以直接写OVERLAPPED x{};
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 列表参数的类型定义
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 关于 C++ 中的函数类型定义
- C++(和 ROS) - 包含与前向声明引用,设置默认值和类型定义
- 将使用/类型定义限制为类范围
- 模板类型定义?
- C++:模板类的类型定义
- 如何对命名空间限定类型进行类型定义?
- 此递归模板类型定义是否有效C++?
- 具有调整对齐方式的类型定义
- C++从抽象类型定义类成员
- 用于C++代码的 API 监视器类型定义 (XML)
- 如何将result_of与函数类型定义一起使用
- 在C++的适当类型定义位置
- 如何根据模板类型定义浮点常量?
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 参数化类的别名(或类型定义)内部类
- 如果我想从类型"T"定义元素的容器(来自 STL),那么"T"必须使用默认构造函数?