析构函数在构造函数后立即调用

时间:2014-07-26 18:58:35

标签: c++ c++11 constructor destructor

我正在尝试创建一个Window类,但由于某种原因,一个Window对象的简单定义之后立即调用它的析构函数。

Window类的标题定义了以下构造函数和复制控件: -

Window();
Window(int);
Window(const char* title);
Window(string title);
Window(const char* title, int x, int y, int width, int height);
Window(string title, int x, int y, int width, int height);
Window(const Window &window);
Window& operator=(const Window &window);
~Window();

这些功能的相关代码如下: -

Window::Window()
{
  Window(default_title, default_width, default_height, default_xpos, default_ypos);
}

Window::Window(int)
:title_(default_title),
size_({ default_width, default_height }),
position_({ default_xpos, default_ypos })
{
  context_ = glutCreateWindow(title_.c_str());
  setposition(position_);
  setsize(size_);
  glutSetWindow(context_);
}

Window::Window(string title)
:Window(title, default_width, default_height, default_xpos, default_ypos)
{ }

Window::Window(const char* title)
{
  string t(title);
  Window(t, default_width, default_height, default_xpos, default_ypos);
}


Window::Window(const char* title, int x, int y, int width, int height)
{
  string t(title);
  Window(t, width, height, x, y);
}

Window::Window(string title, int x, int y, int width, int height)
:title_(title),
size_({ width, height }),
position_({ x, y })
{
  context_ = glutCreateWindow(title.c_str());
  refresh();
  setcallbacks();
  glutSetWindow(context_);
}

Window::Window(const Window &window)
:title_(window.title_),
size_(window.size_),
position_(window.position_)
{
  context_ = glutCreateWindow(title_.c_str());
  refresh();
  glutSetWindow(context_);
}

Window& Window::operator= (const Window &window)
{
  title_ = window.title_;
  size_ = window.size_;
  position_ = window.position_;
  context_ = window.context_;
  refresh();
  glutSetWindow(context_);
  return *this;
}

Window::~Window()
{
  glutDestroyWindow(context_);
}

上面代码中使用的其他函数(例如refresh()和setcallbacks()都没有直接对该类进行祭坛,而是调用glut函数。如果你认为它们是相关的,我会把它们包括在内。

有问题的行如下所示,称为主要功能的一部分: -

Window win("blah");

我已经尝试了几种配置,包括空构造函数,完整的构造函数和赋值,但似乎没有工作。据我所知,构造函数按预期运行并初始化所有变量,然后当它进入main函数中的下一个语句时,莫名其妙地调用析构函数。

2 个答案:

答案 0 :(得分:6)

这是因为你不能像这样调用构造函数:

Window::Window(const char* title, int x, int y, int width, int height)
{
  string t(title);
  Window(t, width, height, x, y); // this create a temporary Window then destroy it
}

而是这样做:

Window::Window(const char* title, int x, int y, int width, int height)
    : Window( string(t), width, height, x, y)
{}

答案 1 :(得分:0)

要了解代码无法正常工作的原因,您需要知道构造函数调用的工作原理。

在默认构造函数中,例如,调用另一个将创建Window对象的构造函数。但是这个新对象被限制在默认的构造函数范围内!因此,当您离开此范围时(默认构造函数调用结束时),通过调用其析构函数来销毁该对象。

你可以观察到这一点,因为在下面的构造函数中,你创建了一个过剩窗口(context_)并设置它:

Window(string title, int x, int y, int width, int height)

然后,在析构函数中,你破坏了这个过剩窗口。请注意,您只调用了限制在默认构造函数范围内的临时对象的析构函数!对默认构造函数的原始调用仍会创建一个Window(一个空的),它将保留在另一个范围内。

要解决此问题并执行您最初想要执行的操作,您需要使用constructor delegation(仅限C ++ 11)。您可以通过在构造函数初始化列表中调用另一个构造函数来执行此操作:

Window::Window(/* some arguments */)
    : Window(/* other arguments (other constructor) */) {
    // other stuff
}

另请注意,您可以使用默认参数。例如:

Window(string title = default_title,
       int x = default_xpos, int y = default_ypos,
       int width = default_width, int height = default_height);

我认为您将坐标与调用中的尺寸进行了交换。