我正在开发一个程序,当我将默认构造函数设置为忽略时,其行为会有所不同。具体来说,我正在构建一个对象,以将其传递给第三方库函数。当我省略默认构造函数时,该函数将按预期工作,但是当我定义它时,该函数将阻塞并且不会返回控制,因此我认为问题是由于构造函数造成的。
下面我显示与该问题有关的代码部分的摘要。
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}中的一些初始化(例如frame
,buffer
和其他未显示的字段) }到构造函数。
答案 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
{
}
我个人更喜欢第一种方法,因为从长远来看它更清晰,更不易出错