我用 1 个非参数构造函数、1 个参数构造函数、2 个复制构造函数、1 个赋值运算符和 1 个加号运算符编写了一个简单的 C++ 类示例。
class Complex {
protected:
float real, img;
public:
Complex () : real(0), img(0) {
cout << "Default constructor\n";
}
Complex (float a, float b) {
cout << "Param constructor" << a << " " << b << endl;
real = a;
img = b;
}
// 2 copy constructors
Complex( const Complex& other ) {
cout << "1st copy constructor " << other.real << " " << other.img << endl;
real = other.real;
img = other.img;
}
Complex( Complex& other ) {
cout << "2nd copy constructor " << other.real << " " << other.img << endl;
real = other.real;
img = other.img;
}
// assignment overloading operator
void operator= (const Complex& other) {
cout << "assignment operator " << other.real << " " << other.img << endl;
real = other.real;
img = other.img;
}
// plus overloading operator
Complex operator+ (const Complex& other) {
cout << "plus operator " << other.real << " " << other.img << endl;
float a = real + other.real;
float b = img + other.img;
return Complex(a, b);
}
float getReal () {
return real;
}
float getImg () {
return img;
}
};
我在 main 中完全像这样使用这个类:
int main() {
Complex a(1,5);
Complex b(5,7);
Complex c = a+b; // Statement 1
system("pause");
return 0;
}
结果打印为:
Param constructor 1 5
Param constructor 5 7
plus operator 5 7
Param constructor 6 12
我认为语句 1 中必须使用复制构造函数,但我真的不知道调用的是哪一个。 请告诉我是哪一个,为什么? 非常感谢
最佳答案
编译器省略了对复制构造函数的调用(实际上,两次 调用)。根据 C++11 标准的第 12.8/31 段,这是允许的(但不是强制的!),即使构造函数或析构函数有副作用:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects. [..] This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):
— in a
returnstatement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value[...]
— when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
如果编译器没有省略对复制构造函数的调用,那么第一个将被选择两次,即具有以下签名的那个:
Complex( const Complex& other )
原因是:
operator + 返回的值是从临时 (Complex(a, b)) 复制初始化的,并且只有 的左值引用const 可以绑定(bind)到临时对象。如果 operator + 是这样写的,事情就会不同:
Complex operator+ (const Complex& other) {
// ...
Complex c(a, b);
return c;
}
在这种情况下,将调用第二个复制构造函数,因为 c 不是 const 限定的并且是左值,因此它可以绑定(bind)到左值引用到非const;
main() 中的对象 c 是从右值复制构造的(operator + 返回的值也是一个临时的)。无论 operator + 如何返回其 Complex 对象,只要它按值返回,都是如此。因此,只要不执行复制省略,就会选择第一个复制构造函数。
如果您正在使用 GCC 并想验证此行为,请尝试设置 -fno-elide-constructors 编译标志(Clang 也支持它,但 3.2 版有一个错误,我没有知道它是否已修复)。
关于c++ - 确定在 C++ 代码中调用了哪些复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16636236/
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我的瘦服务器配置了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
我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的