C ++:如何根据条件选择构造函数?

时间:2014-02-27 08:35:22

标签: c++ scope

假设我有一个具有不同构造函数的类:

class A
{
public:
    A(char* string)
    {
        //...
    }

    A(int value)
    {
        //..
    }

    void check() {}
};

现在我想在堆栈上创建一个A对象,必须根据某些条件选择构造函数,但是有一个问题:创建的对象被销毁然后我们退出{...}阻止。

bool isTrue() { /*...*/ }

int main() 
{
    if (isTrue())
    {
        A a("string");
    }
    else
    {
        A a(10);
    }
    a.check(); //error: 'a' is not defined in this scope
}

假设我没有operator=类中的复制构造函数或A。那怎么能解决这个问题呢? http://ideone.com/YsjmnK

5 个答案:

答案 0 :(得分:5)

A a = isTrue() ? A("string") : A(10);

如果a.check()是const成员函数,则替代方案可能更好:

const A& a = isTrue() ? A("string") : A(10);

当引用a超出范围时,对象将被销毁。

注意,自C ++ 17以来,根据copy elision的规则,对于这种情况,不需要复制/移动构造函数;这里保证复制省略。

从C ++ 17开始,您可以使用std::optional,这不会导致任何动态内存分配。 e.g。

std::optional<A> a;
if (isTrue())
{
    a.emplace("string");
}
else
{
    a.emplace(10);
}
(*a).check();

BTW:A(char* string)应该是A(const char* string)

答案 1 :(得分:3)

您无法满足所有规定的要求。

如果你可以摆脱对象在堆栈上的要求,你可以使用指针。

A *a;
if (isTrue())
    a = new A("string");
else
    a = new A(10);
a->check();
delete a;

答案 2 :(得分:3)

如果类型有默认构造函数,你可以默认构造一个对象,立即破坏它,然后使用相应的构造函数通过placement-new再次构造它:

A a;
a.~A();
if (isTrue())
{
    new(&a) A("string");
}
else
{
    new(&a) A(10);
}

C ++标准有几个与上述类似的示例,只搜索.~->~

请注意,这是超级恶魔。如果您的代码得到审核,您可能会被解雇。

答案 3 :(得分:1)

我刚才有同样的问题,谷歌帮助我找到了这个问题:

unique_ptr<A> foo;

if(isTrue())
    foo = std::unique_ptr<A>(new A("10"));
else
    foo = std::unique_ptr<A>(new A(10));

对OP来说可能为时已晚,但其他人可能希望找到这个有用的。

答案 4 :(得分:-2)

您可以使用模板类:

template<class type> class A
{
protected:
    type    T;
public:

    void A(type t_curr) {T = t_curr;};//e.g.---

    void check() {}
};