【问题标题】:Defining copy constructor in a class inherited from POD struct在继承自 POD 结构的类中定义复制构造函数
【发布时间】:2011-11-25 05:08:07
【问题描述】:

如您所知,如果没有手动定义,编译器会为 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 数据类型的构造函数,如何调用它?

附:上述代码在 VS2010 上编译良好。

P.P.S.我here发布了与这个主题相关的问题。

【问题讨论】:

    标签: c++ copy-constructor


    【解决方案1】:

    BITMAP(frame) 无需强制转换就可以解决问题,因为编译器将知道父级的类型并能够隐式转换参数。请注意,如果您想使用强制转换来明确显示您在做什么,请强制转换为引用类型:BITMAP( static_cast&lt;const BITMAP&amp;&gt;(frame) ),

    另外,请认真考虑这种继承。从现在起一两年后的某个时候,有人会将您的CPreviewFrame 对象删除为BITMAP。最好的情况是它们会泄漏内存,最坏的情况是您需要花费数天或数周的时间来调试应用程序无法正常运行的原因。组合(具有可能在幕后调用 WinAPI 函数的适当接口)通常实现起来并不复杂,并且可以更准确、更正确地在此处对您的问题进行建模。

    或者,您可以使用组合并只为位图部分提供一个吸气剂(如评论中所建议的那样)。这会公开您的类的实现细节,但可能在短期内更容易编写 Win API。

    【讨论】:

    • 我想在显式转换为引用类型的情况下,需要避免创建临时变量?这句话很有用,我会记住的。至于删除它肯定会导致问题,我没有注意到。但是,提供此类功能并保持与 WinAPI 兼容的更好方法是什么? (至于功能 - 它不仅受内存的限制。从位图的角度来看,可以有其他扩展,如预览帧)。也许通过提供 getter 来引用 BITMAP 甚至转换运算符?
    猜你喜欢
    • 2013-03-06
    • 1970-01-01
    • 2021-11-20
    • 2012-05-26
    • 2023-03-18
    • 2019-01-12
    • 1970-01-01
    • 2015-04-11
    相关资源
    最近更新 更多