使用不同的构造函数重新分配对象
Posted
技术标签:
【中文标题】使用不同的构造函数重新分配对象【英文标题】:Reassign object with different constructor 【发布时间】:2014-06-30 07:17:23 【问题描述】:在MyClass
班级,我有一个成员Dialog dialog_
。
调用MyClass
的构造函数后,我想用MyClass
的构造函数中创建的参数为dialog_
调用不同的构造函数(这就是为什么我不能直接为@调用不同的构造函数987654327@,但只是默认的)。
所以我尝试了
dialog_ = Dialog(/* different constr. w/ parameters passed from MyClass */);
但这不起作用。错误是
Error: no operator "=" matches these operands
operand types are: Dialog = Dialog
于是我google了一下,在this SO thread (3rd answer)找到了一个我试过的代码sn-p:
dialog_.~Dialog();
new(&dialog_) Dialog(/* different constr. w/ parameters passed from MyClass */);
而且它有效。线程中的答案虽然指出“这个的价值并没有超出纯粹的理论范围。不要在实践中这样做。整个事情很难描述。”
那么在不使用明显不受欢迎的代码的情况下,我能做些什么来解决我的问题呢?
我希望你能理解我想要达到的目标。谢谢!
【问题讨论】:
顺便说一句,析构函数后跟构造函数是邪恶的。不要这样做。永远。 是的,sn-p 太可怕了。我建议使用某种形式的“assign”/“reassign”方法组合,而不是依赖构造函数。 @RichardHodges 不,我没有使用 C++11。而且我知道这很糟糕,这就是我在这里问的原因,但我缺乏自己解决问题的专业知识^^ 在这种情况下,要么使用我的答案中的选项 1,要么看看你是否可以重构你的类设计,以便它封装你可以在初始化列表中构造的更小的类。 【参考方案1】:有两种方法可以实现您想要的。
在 c++98 中,您需要将一些初始化推迟到您从构造函数调用的 init() 函数。这有点棘手,因为这意味着您的许多成员变量的重复构造和赋值。
在 c++11 中,您可以在初始化器列表中调用 1 个其他构造函数,传递计算值(这些值可以在静态函数中计算以保持整洁)。
如果您提供构造函数代码示例,我可以向您展示如何操作。
【讨论】:
听起来他想延迟成员的初始化。我会为此建议boost::optional
我不知道我们是否在谈论相同的init()
函数,但我之前尝试过。该函数具有与第二个构造函数相同的参数,但与我原来的帖子中的错误相同,除了 Dialog
被另一个作为参数的类替换......我将在下面的另一条评论中解释它:
Dialog
的两个构造函数是Dialog()
和Dialog(DialogType_ type, Resources &resources)
。 DialogType_
只是 Dialog
类中的一个枚举。所以默认构造函数Dialog()
只是空的,而另一个构造函数将type_
初始化为type
和resources_
初始化为resources
(都是成员变量)。
我使用函数init(DialogType_ type, Resources &resources)
时遇到的错误是关于Resources
。它看起来像这样:void Dialog::initialise(DialogType_ type, Resources &resources) type_ = type; resources_ = resources;
。错误在resources_ = resources
行。我希望我能解释一下:/【参考方案2】:
您可以将 Dialog 成员放在 std::unique_ptr 中,然后在需要时替换它:
class MyClass
private:
std::unique_ptr<Dialog> dialog_;
public:
MyClass():
dialog_( /* ... first constructor ... */ )
void setNewDialog(/* parameters */)
dialog_.reset(new Dialog(/* parameters */) );
;
【讨论】:
我从未与std::unique_ptr
合作过,但这听起来是一个不错且简单的想法。如果我使用您的示例,我需要处理new
还是它会自动管理内存?
std::unique_ptr 拥有该对象并在其析构函数中释放它。但请记住,如果您希望您的类可复制,则必须编写一个复制构造函数。【参考方案3】:
我试过的都没有用,所以我就用吧
dialog_.~Dialog();
new(&dialog_) Dialog(/* ... */);
虽然不好
【讨论】:
unique_ptr 解决方案有什么问题?上面的代码属于非常糟糕的黑客级别,只有在你完全知道自己在做什么的情况下才应该使用。 参见***.com/questions/14187006/…:“然而,在一个相当低的级别上管理内存,就像上面显式调用析构函数一样,是糟糕设计的标志。可能,它实际上不仅是糟糕的设计,而且是完全错误的” 我尝试使用 std::unique_ptr 但它在我现有的代码中引入了很多新错误(因为我正在绘制对话框等)。明天当我的挫败感减弱时,我会再次尝试这种方法:P以上是关于使用不同的构造函数重新分配对象的主要内容,如果未能解决你的问题,请参考以下文章