这是我第一次使用 C++0x 右值引用进行实验,似乎发生了一些奇怪的事情。
在下面的代码示例中,工厂函数MakeWindow 按值返回一个Window 对象。调用者使用它来初始化一个 Window 对象。如果我理解正确,这应该调用移动构造函数。为了检测到这一点,我在那里抛出了一个异常。最重要的是,我禁用了复制构造函数:
#include <iostream>
// Fake WinAPI
typedef void* HWND;
HWND CreateWindow() { return (void*)1; }
void DestroyWindow(HWND) { }
// End WinAPI
// C++ WinAPI Wrapper Library
class Window
{
public:
Window(HWND inHandle) :
mHandle(inHandle)
{
std::cout << "Window constructor. Handle: " << inHandle << std::endl;
}
Window(Window && rhs) :
mHandle(rhs.mHandle)
{
std::cout << "Window move constructor. Handle: " << mHandle << std::endl;
rhs.mHandle = 0;
throw 1; // this is my "breakpoint"
}
~Window()
{
std::cout << "Window destructor. Handle: " << mHandle << std::endl;
if (mHandle)
{
DestroyWindow(mHandle);
}
}
private:
Window(const Window&);
Window& operator=(const Window&);
HWND mHandle;
};
// Factory function
Window MakeWindow()
{
return Window(CreateWindow());
}
int main()
{
{
Window window(MakeWindow());
}
std::cout << "Everything is OK." << std::endl;
return 0;
}
但是,代码运行良好,没有抛出此异常。这是控制台输出:
Window constructor. Handle: 0x1
Window destructor. Handle: 0x1
Everything is OK.
如果我注释掉移动构造函数,则编译失败并出现以下错误:
MysteryMove.cpp: In function 'Window MakeWindow()':
MysteryMove.cpp:39:5: error: 'Window::Window(const Window&)' is private
MysteryMove.cpp:49:33: error: within this context
MysteryMove.cpp: In function 'int main()':
MysteryMove.cpp:39:5: error: 'Window::Window(const Window&)' is private
MysteryMove.cpp:57:35: error: within this context
make: *** [all] Error 1
这似乎没有意义。谁能解释一下是怎么回事?
感谢@Philipp,我了解到移动构造函数也可以省略。这在 §12.8/34 和 N3126 draft standard 的脚注 124 中有描述。 .
这里还提到 RVO 只允许用于非 volatile 对象。这意味着我可以像这样编写工厂函数来绕过它:
// Factory function
Window MakeWindow()
{
volatile Window window(CreateWindow());
return const_cast<Window&&>(window);
}
确实有效:
Window constructor. Handle: 0x1
Window move constructor. Handle: 0x1
terminate called after throwing an instance of 'int'
Abort trap
最佳答案
这不是很明显吗?您的代码返回本地临时 Window 的 拷贝:
Window MakeWindow()
{
return Window(CreateWindow());
}
编译器实际上会优化这个拷贝(通过返回值优化)——这就是为什么你的移动构造函数从未真正被调用——但为了正确起见,复制构造函数必须仍然存在。
关于c++ - 移动构造函数似乎没有执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4767620/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试