假设有两个类的层次结构(class Derived: public Base).这两个类都有很大的内存占用和昂贵的构造函数.请注意,这些类中没有任何内容在堆中分配:它们只是有一个大的sizeof.
然后有一个具有快速路径(始终执行)和慢速路径(有条件地执行)的功能.快速路径需要一个Base实例,慢速路径需要一个Derived从现有基础构建的实例.此外,只有在快速路径之后才能做出慢速路径决定.
当前代码如下所示:
void f()
{
Base base;
/* fast path */
if (need_slow_path) {
Derived derived (base);
/* slow path */
}
}
Run Code Online (Sandbox Code Playgroud)
这是低效的,因为需要将基数复制到派生中; 基数也被分配两次,存在堆栈溢出的风险.我想要的是:
Derived例如,分配内存Base给它Derived在现有Base实例上调用ctor 并执行慢速路径在C++中有可能吗?如果没有,有哪些可行的解决方法?显然,我正在努力优化速度.
Rei*_*ica 32
我担心这不可能就像你写的那样 - 任何Derived 必须调用Base子对象的构造函数的构造函数,所以合法地执行它的唯一方法是首先调用Base析构函数,我相信你不希望这样.
但是,通过轻微的重新设计应该很容易解决这个问题 - 更喜欢组合而不是继承,并创建Derived一个单独的类来存储引用(在一般意义上;它当然可以是指针)Base并使用它.如果访问控制是一个问题,我觉得这friend是合理的.
Tan*_*til 11
您应该稍微改变您的设计,以将您对继承的依赖性改为对组合的依赖.
您可以将派生类的成员(不存在于基类中)封装到另一个类中,并在派生类中保留它的空引用.
现在直接初始化派生类而不初始化新类的对象.
每当需要慢速路径时,您都可以初始化并使用它.
优点
我可以假装它.
移动/衍生为所有的数据optional(它是boost或std::ts::optional建议用于交C++ 14,或手轧).
如果你想慢速路径,初始化optional.否则,请保留为nullopt.
将有一个bool开销,并在您分配/比较/销毁隐式时进行检查.像virtual函数一样的东西derived(即你必须手动管理动态的dispath).
struct Base {
char random_data[1000];
// virtual ~Base() {} // maybe, if you intend to pass it around
};
struct Derived:Base {
struct Derived_Data {
std::string non_trivial[1000];
};
boost::optional< Derived_Data > m_;
};
Run Code Online (Sandbox Code Playgroud)
现在我们可以创建一个Derived,只有在我们构建m_.emplace()了Derived_Dataget 之后.仍然存在的一切都在一个连续的内存块中(如果构造的话,bool由optional轨道注入m_).