C++显式调用构造函数初始化对象有用到拷贝构造函数么?

下面代码中的HasPtr hp4 = HasPtr(1,str);
这里有用到拷贝构造函数,拷贝构造函数中的语句“调用拷贝构造函数”
并没有输出。
但是将拷贝构造函数中的const去掉变成HasPtr(  HasPtr& hp)又报错了,
拷贝构造函数中的第一个参数必须是引用类型,但未必是const吧?
而且从正确使用时的输出看,这里拷贝构造函数HasPtr( const HasPtr& hp)并没有调用啊

#include <iostream>
#include <memory>

using std::string;
using std::cout;
using std::endl;

class HasPtr{
public:
	HasPtr() = default;
	HasPtr( int i1,string &str ){
		i = i1;
		ps = &str;
	}
	HasPtr( const HasPtr& hp){
		i = hp.i;
		ps = new string( *hp.ps );
		cout<<"调用拷贝构造函数"<<endl;
	}
	int i;
	string *ps;
};
int main(  ){
	string str = "hello";
	HasPtr hp4 = HasPtr(1,str);
	cout<<hp4.i<<" "<<hp4.ps<<endl;
	return 0;
}

全部评论
楼上说的让我也很疑惑啊……这怎么算是委托构造呢…… HasPtr hp4 = HasPtr(1,str); 正常情况下,这句应该是先生成一个临时对象,然后拷贝构造给hp4。这里我觉得应该是编译器优化把临时对象的生成给省略了。所以其实最后跟 HasPtr hp4(1,str); 没有本质区别。
点赞 回复 分享
发布于 2017-07-16 20:30
拷贝构造函数的调用情况
点赞 回复 分享
发布于 2017-07-16 16:09
我思考了一下。 HasPtr hp4 = HasPtr ( 1 ,str); 先调用了 HasPtr( int i1, string &str )构造函数,构造出一个临时右值对象。 然后右值对象通过 HasPtr( const HasPtr & hp)拷贝构造,传给hp4. 但是,这样是错的= =,为什么没有调用拷贝构造函数啊。 大佬解释一下,我也迷糊了
点赞 回复 分享
发布于 2017-07-16 17:19
编译器优化靠谱,试试关闭所有优化
点赞 回复 分享
发布于 2017-07-16 20:42
不知道怎么关闭优化,直接使用比较老的Vc++6.0,结果是调用了拷贝构造函数。 #include <iostream> #include <memory> using namespace std; class HasPtr{ public: HasPtr() { } HasPtr( int i1,string &str ){ i = i1; ps = &str; } HasPtr( HasPtr& hp){ i = hp.i; ps = new string( *hp.ps ); cout<<"调用拷贝构造函数"<<endl; } HasPtr& operator=( HasPtr& hp){ cout<<"调用拷贝赋值运算符"<<endl; i = hp.i; ps = hp.ps; return *this; } int i; string *ps; }; int main( ){ string str = "hello"; HasPtr hp4 = HasPtr(1,str); cout<<"hp4建立完成"<<endl; HasPtr hp1(1,str); HasPtr hp2 = hp1; cout<<"hp3拷贝初始化完成"<<endl; HasPtr hp3; hp3 = hp1; HasPtr* hp5 = new HasPtr(1,str); return 0; } 输出  调用拷贝构造函数  hp4建立完成  调用拷贝构造函数  hp3拷贝初始化完成  调用拷贝赋值运算符  这里HasPtr( HasPtr& hp)去掉了const,也是对的,本来就觉得这里可以不用const修饰 奇怪的是用eclipse,如果说没使用拷贝构造函数为什么忽略掉const就报错, 没调用的话怎么会报错?而且原因也不知道  #include <iostream> #include <memory> using namespace std; class HasPtr{ public: HasPtr() = default; HasPtr( int i1,string &str ){ i = i1; ps = &str; } HasPtr(/*const*/ HasPtr& hp){ i = hp.i; ps = new string( *hp.ps ); cout<<"调用拷贝构造函数"<<endl; } int i; string *ps; }; int main( ){ string str = "hello"; HasPtr hp4 = HasPtr(1,str); cout<<hp4.i<<" "<<*hp4.ps<<endl; return 0; } 上面的代码eclipse报错:invalid initialization of non-const reference of type 'HasPtr&' from an rvalue of type 'HasPtr' 如果删除掉自己定义的拷贝构造函数,使用默认的不会报错。
点赞 回复 分享
发布于 2017-07-16 21:51
cxx 98/03里, HasPtr hp4 = HasPtr(1,str); 语法上讲,是调用拷贝构造,而HasPtr(1,str)是个右值,是带const的,(不过cxx 11及以上,是右值引用),HasPtr(HasPtr &),这种,自然就编译不过了; 之所以没用到,那是编译器优化,叫做copy elision,实际就是直接调用了一次构造,没有出现临时对象,印象中这个功能VC是关不掉的,g++可以通过--fno-elide-constructors选项关闭;
点赞 回复 分享
发布于 2017-07-16 22:50

相关推荐

点赞 评论 收藏
分享
HNU_fsq:建议直接出国,这简历太6了。自愧不如
点赞 评论 收藏
分享
专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务