c++ - 如何在不调用复制构造函数的情况下将返回值隐式转换为基类?
问题描述
考虑两个类,例如:
#include <cstdio>
using std::puts;
class Base {
public:
Base() { puts("Create base"); }
Base(const Base &) { puts("Copy base"); }
Base(Base &&) { puts("Move base"); }
virtual ~Base() { puts("Delete base"); }
Base & operator=(const Base &) = delete;
};
class Derived : public Base {
public:
Derived() { puts("Create derived"); }
Derived(const Derived &) { puts("Copy derived"); }
Derived(const Base &) { puts("Copy derived from base"); }
Derived(Derived &&) { puts("Move derived"); }
Derived(Base &&) { puts("Move derived from base"); }
virtual ~Derived() { puts("Delete derived"); }
Derived & operator=(const Derived &) = delete;
};
和一个功能:
Base fn() {
Derived d;
// Fill in d here
return d;
}
复制基类是一项非常昂贵的操作,但是由于派生类没有太大不同,因此可以使用移动语义将其转换为基对象。但是,我无法让编译器隐式使用它而不是复制构造。我尝试添加以下内容但没有成功:
Base::Base(Derived &&);
Derived::operator Base &&() &&;
Derived::operator Base() &&;
有没有办法通过只更改两个类而不是函数来避免复制构造函数fn
?
编辑:如果我可以更改功能,我知道该怎么做,fn
但我不能。
解决方案
Base::Base(Derived &&);
如果添加正确,将正常工作。
#include <utility>
class Derived;
class Base {
// ...
Base(Derived &&);
};
// Derived here
Base::Base(Derived &&d) : Base(std::forward<Base>(d)) {}
唯一棘手的部分是std::forward<Base>(d)
. 但它最终只是一个演员表,我们要求d
作为一个Base
xvalue 转发。然后委托的移动构造函数做正确的事情。
RVO 保证会尝试返回局部变量,就好像它首先是右值一样。由于现在有一个与之匹配的构造函数,因此它将起作用。
推荐阅读
- react-native - 我如何看到 react-native 的性能下降
- java - Jgit - 从分支获取所有提交
- javascript - Javascript:无法在具有多行的表上获取元素 ID
- django - 在自定义迁移中将模型导入为 `apps.get_model('app_name', 'ModelName')` 的逻辑是什么
- codec - Moviepy,更快地提取剪辑
- java - 多次切换片段时Android App崩溃
- python-3.x - Python 在函数中使用 del 关键字
- php - 将 timeatmp 添加到 SELECT
- reverse-engineering - 使用 CRC RevEng 查找正确的 CRC
- r - 散点图上的重叠线图