【问题标题】:Call different constructor conditionally [duplicate]有条件地调用不同的构造函数[重复]
【发布时间】:2017-07-19 18:22:52
【问题描述】:

我想根据运行时条件调用同一类的不同构造函数。构造函数使用了不同的初始化列表(: 之后的一堆东西),所以我无法在构造函数中处理条件。

例如:

#include <vector>
int main() {
    bool condition = true;
    if (condition) {
        // The object in the actual code is not a std::vector.
        std::vector<int> s(100, 1);
    } else {
        std::vector<int> s(10);
    }
    // Error: s was not declared in this scope
    s[0] = 1;
}

我想我可以使用指针。

#include <vector>
int main() {
    bool condition = true;
    std::vector<int>* ptr_s;
    if (condition) {
        // The object in the actual code is not a std::vector.
        ptr_s = new std::vector<int>(100, 1);
    } else {
        ptr_s = new std::vector<int>(10);
    }
    (*ptr_s)[0] = 1;
    delete ptr_s;
}

如果我不为我的类编写移动构造函数,有没有更好的方法?

【问题讨论】:

  • 但它不是 std::vector。这是我写的一门课。这只是一个例子。
  • 恕我直言。那为什么要以std::vector 为例。它显然具有可以使这项任务轻松完成的方法。无论如何,您的 real 类是否支持移动分配或交换?
  • @WhozCraig:我想我在某处看到了类似使用三元运算符的东西,但我不确定。不,这个类是一堆类的组合,其中大多数没有移动构造函数。
  • 嗯,是的,三元运算符(在此示例中使用 两次)可以工作。读起来会有点神秘,但可以肯定。 std::vector&lt;int&gt; v((condition?100:10), (condition?1:0));。你的同事会因此你,顺便说一句,老实说,重新考虑这个。
  • 在您的示例中,您正在调用相同的构造函数,但使用不同的值,这种情况比使用不同的构造函数更容易,因为您可以将要在构造函数中传递的值保存在一些临时变量中和之后if else 语句构造你的对象。

标签: c++ constructor


【解决方案1】:

另一种解决方案是创建一个类,默认构造函数不会进行分配、计算(以及所有艰苦的工作),而是具有一个函数,例如 initialize 并为每个构造函数类型重载它以执行真正的工作。

例如:

int main() {
    bool condition = true;
    SomeClass object;
    if (condition) {
        object.initialize(some params 1)
    } else {
        object.initialize(some params 2)
    }
}

或者,您可能希望默认构造函数在这种情况下做一些有意义的事情,使构造函数接受某种“虚拟”类型的对象,例如DoNothing 改为:

 SomeClass object(DoNothing())

【讨论】:

  • 请注意这违反了 RAII 原则并会产生一些影响。 IE。一个新构建的对象还没有准备好使用,你应该提防它。使用这种方法确保正确性会使设计复杂化,并引入大量用于检查的样板(或涉及为调用未初始化对象的方法编写异常)。
  • @luk32 我相信答案的最后一部分对这个问题有一点帮助,因为用户有点明确要求“懒惰”初始化。但通常当然必须小心使用它。
  • @luk32 有哪些替代方案?初始化类需要从硬盘读取大量数据,然后在两个构造函数创建的对象之间同步数据。我很难第二次初始化不是最好的情况,但不知道替代方案。在这种情况下,复制构造函数很糟糕。我猜写很多移动构造函数是唯一的选择?
  • 如果我使用优化,希望 cop 省略有效。 stackoverflow.com/questions/26959846/move-semantics-in-eigen
【解决方案2】:

你就不能做一些类似的事情

std::vector<int> ptr_s;
if (condition) {
    ptr_s.resize(100);
} else {
    ptr_s.resize(10);
}

?

【讨论】:

  • 它不是实际代码中的 std:vector。所以我不能
  • 那你为什么不用你的真实代码发布SSCCE
  • 因为真实的代码太长了。然后有人会说写移动构造函数。实际代码需要很长时间。这意味着为类和构成该类的每个类编写移动构造函数。
  • 这就是 SSCCE 的“简单”部分的用武之地。将实际代码简化到能够说明问题的程度,仅此而已,然后发布。
猜你喜欢
  • 2013-05-22
  • 1970-01-01
  • 2015-01-20
  • 2013-11-18
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多