Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

构造函数 #2

Open
chlict opened this issue Aug 31, 2019 · 0 comments
Open

构造函数 #2

chlict opened this issue Aug 31, 2019 · 0 comments

Comments

@chlict
Copy link
Owner

chlict commented Aug 31, 2019

右值:
字面量(如10, 'a')和临时对象(如A())

"区分左值和右值的一个简单办法是:看能不能对表达式取地址,如果能,则为左值,否则为右值。"

const A& 和A&& 都会引用到临时对象,但是A&&的优先级更高

auto a = A();不会调用copy/move constructor,只会调用普通的constructor,实际上就是在栈上分配一块空间,执行构造函数,只有一个对象,等价于A a();
而a = A();(a是一个已有对象)会调用copy/move assignment,因为存在两个对象:先构造一个临时对象A(),再赋值给a,如果A有move assignment,则优先调用move assignment

值得注意的是,foo_by_value(A())不会调用copy/move constructor,仍然是栈上构造一个对象,类似auto a = A();
foo_by_value(a)永远会调用copy constructor
foo_by_ref(A()),foo_by_ref(const A&)和foo_by_ref(A&&)都合法,两者都存在时优先匹配A&&

对于返回值是struct的函数,编译器有return slot优化,直接在父函数的栈帧上构造对象,而不是现在本函数构造对象,再拷贝给父函数,编译器会把父函数栈帧上return slot的地址传给本函数
auto a = foo() {return A();} 不会调用copy/move constructor,直接在父函数栈帧上用A()构造a
A a = foo() { return A(); }同上
a = foo() { return A(); },现在父函数上构造一个临时对象,然后copy/move assignment给a

a5 = f4(): Copy constructor? -- no
Constructing 0x7fffdb9e7ec0 with parm 5
[Enter f4]:
-- outside
Move assignment: &other = 0x7fffdb9e7ec0, other.a = 5, this = 0x7fffdb9e7ea8, this->a = 5

重点区分:
auto a = A();
auto a = foo() { return A(); }
都不会调copy constructor,只有一次default constructing

foo_by_value(A());
foo_by_value(a);
一个不调copy constructor,一个要调

注:以上结果是g++/clang++默认对构造函数优化的结果,如果加了-fno-elide-constructors,结果会很不一样

那么move constructor的意义是什么?
copy constructor一般是深拷贝,保证两个对象各自拥有独立的资源。而如果src对象是个临时对象,不需要有独立资源时,用move constructor做浅拷贝就好了:
auto a = foo() { return A(); } 或 A a = foo() { return A(); }

move assignment适用场景:
a = A();
a = foo() { return A(); }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant