在从 POD 结构继承的类中定义复制构造函数
如您所知,如果没有手动定义,编译器会为 POD 结构定义默认构造函数、复制构造函数、赋值运算符和析构函数。通常(或者也许我应该说总是)这是一个有点复制操作。因此,我决定从 Win 结构 BITMAP 继承我的类,以在构造函数中提供内存分配并在析构函数中提供内存释放。我没有使用组合,因为我想允许将它与一些 WinAPI 函数一起使用。这是一段代码:
class CPreviewFrame : public BITMAP
{
public:
CPreviewFrame( );
CPreviewFrame( std::size_t width, std::size_t height, UCHAR bytesPerPixel = 3 );
CPreviewFrame( const CPreviewFrame& frame );
~CPreviewFrame( );
.....
};
复制构造函数的定义如下:
CPreviewFrame::CPreviewFrame( const CPreviewFrame& frame ):
BITMAP( static_cast<BITMAP>(frame) ), //question is here
m_bufferSize( frame.m_bufferSize )
{
bmBits = new uint8_t[ m_bufferSize ];
memcpy( bmBits, frame.bmBits, m_bufferSize );
}
所以我的问题是:从继承结构调用编译器定义的复制构造函数是否正确,或者我应该在构造函数体中手动复制所有字段?这两种变体对我来说都有些奇怪,因为尽管编译器定义了 POD 结构,但它们不能有构造函数。如果 POD 数据类型根据定义不存在,如何调用它的构造函数?
上面提到的PS代码在VS2010上编译得很好。
PPS 我发布了与此主题相关的问题
As you know compiler defines default constructor, copy constructor, assignment operator and destructor for POD structures if it weren't defined manually. Usually (or maybe should I say always) it's a bit copy operation. So I've decided to inherit my class from Win structure BITMAP to provide memory allocation in constructor and freeing in destructor. I haven't used composition 'coz I want to allow using it with some WinAPI functions. Here is a some piece of code:
class CPreviewFrame : public BITMAP
{
public:
CPreviewFrame( );
CPreviewFrame( std::size_t width, std::size_t height, UCHAR bytesPerPixel = 3 );
CPreviewFrame( const CPreviewFrame& frame );
~CPreviewFrame( );
.....
};
And copy constructor is defined something like that:
CPreviewFrame::CPreviewFrame( const CPreviewFrame& frame ):
BITMAP( static_cast<BITMAP>(frame) ), //question is here
m_bufferSize( frame.m_bufferSize )
{
bmBits = new uint8_t[ m_bufferSize ];
memcpy( bmBits, frame.bmBits, m_bufferSize );
}
So my question is: Is it proper way to call compiler defined copy constructor from inherited structure or should I copy all fields manually in constructor body? Both variants look somewhat strange for me because POD structs can't have constructors despite compiler defines them. How can you call constructor for POD data type if it doesn't exist by definition?
P.S. Code mentioned above compiles well on VS2010.
P.P.S. There is related question to this theme posted by me here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
BITMAP(frame)
无需强制转换即可完成此操作,因为编译器将知道父级的类型并能够隐式转换参数。请注意,如果您想使用强制转换来显式显示您正在执行的操作,请强制转换为引用类型:BITMAP( static_cast(frame) ),
另外,请认真考虑这一点遗产。一两年后的某个时候,有人会以
BITMAP
的形式删除您的一个CPreviewFrame
对象。最好的情况是它们会泄漏内存,最坏的情况是您花费数天或数周的时间来调试应用程序无法正常工作的原因。组合(具有可以在幕后调用 WinAPI 函数的适当接口)通常实现起来并不复杂,并且它将在这里更准确、更正确地对您的问题进行建模。或者,您可以使用组合,只为位图部分提供一个吸气剂(如评论中所建议的)。这会公开类的实现细节,但可能会使短期内编写 Win API 变得更容易。
BITMAP(frame)
will do the trick with no cast needed as the compiler will know the type of the parent and be able to implicitly convert the argument. Note that if you want to use a cast to explicit show what you're doing, cast as a reference type:BITMAP( static_cast<const BITMAP&>(frame) ),
Also, seriously consider this inheritance. Sometime a year or two from now someone's going to delete one of your
CPreviewFrame
objects as aBITMAP
. Best case they leak memory, worst case you spend days or weeks debugging why the app isn't working right. Composition (with an appropriate interface that may call WinAPI function behinds the scene) isn't typically that complicated to implement and it will more accurately and correctly model your problem here.Alternately you could use composition and just provide a getter to the bitmap portion (as suggested in a comment). This exposes implementation details of your class but might make it easier to code to the Win API in the short term.