假设我有一个具有不同构造函数的类:
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
答案 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() {}
};