简体   繁体   English

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

[英]C++: how to choose the constructor depending on the condition?

Assume I have a class with different constructors: 假设我有一个具有不同构造函数的类:

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

    A(int value)
    {
        //..
    }

    void check() {}
};

Now I want to create an A object on stack, the constructor must be choosed depending on some condition, but there is a problem: the created object is destroyed then we quit {...} block. 现在我想在堆栈上创建一个A对象,必须根据某些条件选择构造函数,但是有一个问题:创建的对象被破坏,然后我们退出{...}块。

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

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

Suppose I haven't the copy-constructor or operator= in the A class. 假设我在A类中没有copy-constructor或operator= So how can solve this issue? 那么如何解决这个问题呢? http://ideone.com/YsjmnK http://ideone.com/YsjmnK

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

And if a.check() is a const member function, an alternative may be better: 如果a.check()是const成员函数,则替代方法可能更好:

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

The object will be destroyed when the reference a go out of scope. 当参考对象将被销毁a走出去的范围。

Note since C++17, according to the rule of copy elision the copy/move constructor is not required to be accessible for this case; 因为C ++ 17注意,根据规则复制省略成为该情况下可访问的复制/移动的构造不是必需的; copy elision is guaranteed here. 这里保证复制省略。

And since C++17 you can use std::optional , which doesn't cause any dynamic memory allocation. 从C ++ 17开始,您可以使用std :: optional ,它不会引起任何动态内存分配。 eg 例如

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

BTW: A(char* string) is supposed to be A(const char* string) . 顺便说一句: A(char* string)应该是A(const char* string)

You can't satisfy all your stated requirements. 您不能满足所有陈述的要求。

If you can get rid of the requirement for the object to be on stack, you could use a pointer. 如果可以摆脱将对象放在堆栈上的要求,则可以使用指针。

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

If the type has a default constructor, you can default-construct an object, immediately destruct it, and then construct it again with the appropriate constructor via placement-new: 如果类型具有默认构造函数,则可以默认构造一个对象,立即对其进行销毁,然后使用适当的构造函数通过placement-new重新构造它:

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

The C++ standard has several examples similar to the above, just search for .~ and ->~ . C ++标准有几个类似于上面的示例,仅搜索.~->~

Note that this is ultra evil. 请注意,这是超邪恶的。 If your code ever gets reviewed, you are probably going to get fired. 如果您的代码曾经被审查过,您可能会被解雇。

I had the exact same question a while ago and this is what google helped me find: 我前一阵子有完全相同的问题,这是谷歌帮助我找到的:

unique_ptr<A> foo;

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

Its probably too late for the OP but someone else might hopefully find this useful. 对于OP来说可能为时已晚,但希望其他人可能会觉得有用。

You can use the template class: 您可以使用模板类:

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

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

    void check() {}
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM