初始化对堆栈变量多态 [英] Initialize Polymorphic Variable on Stack

查看:199
本文介绍了初始化对堆栈变量多态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来到C ++与Java的背景,我想通过初始化类型的变量设置一些多态性$ C​​ $ C A 有两种实现方式之一, B C

Coming to C++ with a Java background, I'd like to set up some polymorphic code by initializing a variable of type A with one of two implementations, B or C.

我的问题是,是否有一个简单的方法来做到这一点的在堆栈中。的我在那里我只使用情况 A 该方法体内,并希望它在函数结束时被销毁,所以触摸堆是可选的。

My question is whether there is an easy way to do this on the stack. I have a case where I'm only using A inside the method body, and want it destroyed at the end of the function, so touching the heap is optional.

下面是我会怎么做堆:

A* a = NULL;
if (p) {
  B* b = new B();
  b->setSomethingImplementationSpecific();
  a = b;
}
else {
  a = new C();
}

doSomething(a);
delete(a);

在实践中我可能会拉了这一点,到工厂方法,并使用的auto_ptr 来避免删除(一)

In practice I'd probably pull this out into a factory method, and use an auto_ptr to avoid the delete(a).

这工作,但我可以做到这一点在堆栈上?我的思维模式是这样的:

This works, but can I do it on the stack? My thought pattern is something like this:

A* a = NULL;
if (p) {
  B b;
  b.setSomethingImplementationSpecific();
  a = &b;
}
else {
  C c;
  a = &c;
}

doSomething(a);

现在我没有与来打扰删除(一),但 DoSomething的(A)荣获'将不起作用,因为 B C ,当他们走出去的范围被破坏。

Now I don't have to bother with delete(a), but doSomething(a) won't work, since the B or C is destroyed when they go out of scope.

我一直在试图想出一个办法做三元运算符的一部分为好,但我最终都borking了语法,并采取临时的地址 - 所以我是正确的,有没有办法做到这一点?

I've been trying to figure out a way to do part of it with the ternary operator as well, but I end up both borking up the syntax and taking the address of a temporary -- so am I right that there is no way to do this?

A * const a = &(p ? B() : C());

这是它是否落实摆在首位在堆栈上的多态性一个愚蠢的想法的建议是值得欢迎的,但主要是我想的独立设计感,以更好地理解C / C的极限++在这个领域。

Advice on whether it's a silly idea to implement polymorphism on the stack in the first place is welcome, but mostly I'm trying to better understand the limits of C/C++ in this area, independently of design sense.

推荐答案

您可以做到这一点用干净的 的std :: aligned_union 存储:

You can do this cleanly using std::aligned_union for storage:

template <typename...T>
using storage_t = typename std::aligned_union<0, T...>::type;

和一个自定义的的unique_ptr 的删除:

and a custom unique_ptr deleter:

struct placement_deleter {
  template <typename T>
  void operator () (T* ptr) const {
    ptr->~T();
  }
};

template <typename T>
using stack_ptr = std::unique_ptr<T, placement_deleter>;

在使用所得:

storage_t<B, C> storage;
stack_ptr<A> a;
if (p) {
  auto b = new (&storage) B();
  a.reset(b);
  b->setSomethingImplementationSpecific();
} else {
  a.reset(new (&storage) C());
}

doSomething(*a);

亲身体验在Coliru

这篇关于初始化对堆栈变量多态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆