C ++中的自定义默认构造函数和默认默认构造函数有什么区别

时间:2019-10-05 02:44:46

标签: c++

我正在开发一个程序,当我将默认构造函数设置为忽略时,其行为会有所不同。具体来说,我正在构建一个对象,以将其传递给第三方库函数。当我省略默认构造函数时,该函数将按预期工作,但是当我定义它时,该函数将阻塞并且不会返回控制,因此我认为问题是由于构造函数造成的。

下面我显示与该问题有关的代码部分的摘要。

class Config {
public:
    typedef std::shared_ptr<Config> SPtr;

    int frame;
    int numSolidParticles = 0;
    bool shapesChanged = false;

    Buffer* buffer;
    FlexParams params;  // struct

    // if omitted then the 3rd party method works as expected
    Config() {
    }
};

...

Config::SPtr config = std::make_shared<Config>();

initialize(config);

...
SetFlexParams(config->params);
// calls to other 3rd party methods that depends on config
...

// call 3rd party library's method that causes the issue
mapBuffer(config->buffer);

更新:我正在尝试移动方法{{1}中的一些初始化(例如framebuffer和其他未显示的字段) }到构造函数。

3 个答案:

答案 0 :(得分:1)

  

自定义默认构造函数和   默认的默认构造函数?

给出一个类X,如果:([class.ctor]/5

  
      
  • X是一个联合,其联合成员具有不平凡的默认构造函数,而X的联合成员中没有默认成员   初始化程序,

  •   
  • X是一个非联盟类,它的变体成员M具有非平凡的默认构造函数,并且没有匿名的变体成员   包含M的并集具有默认的成员初始化程序,

  •   
  • 任何没有默认成员初始化程序的非静态数据成员都是引用类型

  •   
  • 任何没有 brace-or-equal-initializer 的const限定类型的非变量非静态数据成员(或其数组)都没有   用户提供的默认构造函数,

  •   
  • X是一个联合,其所有变体成员都是const限定类型(或其数组),

  •   
  • X是一个非联盟类,任何匿名联合成员的所有成员均为const限定类型(或其数组),

  •   
  • 任何可能构造的子对象,除了具有 brace-or-equal-initializer 的非静态数据成员外,其类类型为M   (或其数组),并且M没有默认构造函数,或者   用于查找M的对应构造函数的重载分辨率   导致模棱两可或导致功能被删除或   从默认的默认构造函数无法访问,或者

  •   
  • 任何可能构造的子对象都具有带有析构函数的类型,该析构函数已从默认默认值中删除或无法访问   构造函数。

  •   

然后将默认的默认构造函数X定义为已删除,而手写的X() {}将格式不正确。

否则,没有区别。

答案 1 :(得分:0)

尽管这不能回答主要问题,但我想解释一下问题是由于我忘记初始化的FlexParams结构的字段引起的。

此结构将大量参数分组到在initialize函数中初始化的第三方库。有趣的是,当我不定义构造函数时,该字段被初始化为0(幸运的是,它是正确的值),而当我定义该构造函数时,该字段则为随机值。

正如您在评论中提到的那样,唯一合理的解释是该问题是由未定义的行为引起的。

答案 2 :(得分:0)

默认默认构造函数会执行您的手动默认构造函数不会做的一件事:它正确地默认构造了成员。我很确定,如果您执行以下任一操作,您的代码将神奇地开始工作:

选项1:明确说明所有成员的默认值(不仅仅是您为此设置的两个成员)

int frame = 0;
int numSolidParticles = 0;
bool shapesChanged = false;

Buffer* buffer = nullptr;
FlexParams params = {};  // struct

选项2:记住初始化构造函数中所有不可平凡的成员

Config()
  : frame{0}
  , numSolidParticles{0}
  , shapesChanged{false}
  , buffer{nullptr}
  , params{} // I think this is the code generated by your compiler for the default default constructor
{
}

我个人更喜欢第一种方法,因为从长远来看它更清晰,更不易出错