[英]Destructor called immediately after constructor
我試圖創建一個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");
我已經嘗試了幾種配置,包括空的構造函數,完整的構造函數和賦值,但似乎沒有一個起作用。 據我所知,構造函數將按預期運行並初始化所有變量,然后在前進到主函數中的下一條語句時莫名其妙地調用析構函數。
這是因為您不能像這樣調用構造函數:
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)
{}
要了解為什么代碼無法按預期運行,您需要知道構造函數調用的工作方式。
例如,在默認構造函數中,調用另一個將創建Window對象的構造函數。 但是這個新對象被限制在默認的構造函數范圍內! 因此,當您離開此作用域時(默認構造函數調用結束時),將通過調用其析構函數來銷毀該對象。
您可以觀察到這一點,因為在以下構造函數中,您創建了一個glut窗口( context_
)並將其設置為:
Window(string title, int x, int y, int width, int height)
然后,在析構函數中銷毀該過剩窗口。 注意,您只調用了限制在默認構造函數作用域內的臨時對象的析構函數! 對默認構造函數的原始調用仍然會創建一個Window
(一個空Window
),該Window
停留在另一個作用域中。
要解決此問題並執行您最初想要做的事情,您需要使用構造函數委托 (僅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);
而且我認為您在通話中將坐標替換為尺寸。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.