如何在堆栈上创建垃圾收集的结构副本?
来自C ++背景,我的第一个猜测就是像下面这样的复制构造函数,但它对于D来说似乎不是很惯用,我在任何一个D项目中都没有看到过我已经看过了。
struct Foo {
immutable int bar;
this(int b) { bar = b; }
// A C++-style copy constructor works but doesn't seem idiomatic.
this(ref const Foo f) { bar = f.bar; }
}
void main()
{
// We initialize a Foo on the stack
auto f = Foo(42);
// Now I want to get a heap copy of its member. How?
// A C++-style copy constructor works but doesn't seem idiomatic.
Foo* f1 = new Foo(f);
}
答案 0 :(得分:8)
您的示例过于复杂,甚至无法编译,但实质上,它听起来像您希望能够做的就像
struct Foo
{
int i;
}
void main()
{
auto f = Foo(5);
auto g = new Foo(f);
}
没有任何特殊构造函数你可以做什么
void main()
{
auto f = Foo(5);
auto g = new Foo;
*g = f;
}
但显然这比你想要的更多步骤。 D的正常“复制构造函数”是一个postblit构造函数,它被声明为this(this) {...}
,但Foo
不需要它,因为它在这里被声明(因为它的所有成员都是值类型),并且它无论如何都无法在堆上分配结构 - 只需复制结构。可以说
auto f = Foo(5);
auto g = new Foo(f);
应该可以正常工作,但目前它没有,并且遗憾的是,语言中没有支持为您定义它。所以,不幸的是,我认为你目前被迫做一些类似于你想要避免的事情。 e.g。
struct Foo
{
int i;
this(int j)
{
i = j;
}
this(Foo rhs)
{
this = rhs;
}
}
void main()
{
auto f = Foo(5);
auto g = new Foo(f);
}
但是,我刚刚打开an enhancement request来使new Foo(foo)
正常工作,并且随着dmd(2.066)的下一个版本,我们将获得原始类型的通用构造(例如new int(5)
现在可以工作了),所以我认为这也是一个很好的论据。
现在,你将不得不提供一个额外的构造函数来实现它。
答案 1 :(得分:4)
[s].ptr
会将结构s
复制到堆中,并获取指向它的指针。