成员变量的新放置位置
问题描述:
我有一个具有GUI成员变量的类。我必须在施工时提供文字,字体和大小。不幸的是,拥有类的构造函数没有得到这些数据,但必须从工厂(特别是字体)获取。成员变量的新放置位置
class Element {
public:
Element();
/* other stuff */
private:
UIElement uie;
};
Element::Element() /* cannot construct the object here */ {
/* ... some aquiring ... */
new (&uie) UIElement(/* now I have the required data */);
}
这是一个有效的实施?我是否可以简单地将物体放置到已建造Element
课程的空间中?
答
您在代码/* cannot construct the object here */
中发表评论,但事实是在输入复合语句之前构造的成员是。
这是一个有效的实施?我可以简单地将对象放入已经由构造Element类分配的空间中吗?
否。在您可以使用放置新功能之前,必须首先销毁默认的构造成员 - 除非该成员可以被破坏。
然而,这是毫无意义的。无论你在复合语句中可以做什么,你也可以在初始化列表中执行。如果一个表达式不够用,那么你可以简单地写一个单独的函数,然后调用它。
UIElement init_uie(); // could be a member if needed
Element::Element() : uie(init_uie()) {
答
一种选择是分解出的初始化代码:
Element::Element() : uie(get_uie()) {}
UIElement get_uie(){
/* ... some aquiring ... */
return UIElement(/* now I have the required data */);
}
你也可以做它内嵌没有这样的额外功能,但它无疑是难以阅读:
Element::Element() : uie(
[]{
/* ... some aquiring ... */
return UIElement(/* now I have the required data */);
}()
){}
只需使用作业。你的编译器会优化副本。 – Qix
这看起来不正确的C++代码 - 你正在新建一个堆栈变量。 –
至少,您需要调用现有的'Element'对象的析构函数。但是这对我来说似乎是很糟糕的设计。为什么不只是用'Element'的两阶段施工设计?或者,如果失败了,则为成员变量分配一个新的'Element'对象,并让优化器处理它。 –