声明 RValue 方法(例如 void operation() 和 &;) 虚拟 C++1x )是否有意义
Makes it any sense to declare RValue methods (e.g. void operation() &&;) virtual C++1x
这可能有点异国情调:(我正在努力更新到新的c ++标准(在类中声明 RValue 方法是否有任何有意义的情况例如 void operation() &&;
virtual
?我无法想象,因为操作仅适用于临时对象,例如 Base().operation()
或Derived().operation()
或类似createObject().operation()
的东西.表达式createObject()
必须返回一个对象和不是引用也不是指针,因为它们必须同时存在引用左值对象。并且由于类型切片,总是调用Base::operation()
。如果你有一个对象 Derived()
,则调用Derived::operation()
,然而,无论它是否Base
都是虚拟的。那么,我监督过什么案例吗?感谢您的启发!
哦,对了,我忘了,RValue有演员:前进和前进!谢谢!
我的发现是:1. 调用 RValue 参考合格操作 (rqOp(( &&(,我们总是必须使用 std::forward<.。>除了:Derived((.rqOp((;2. 声明 RValue 参考合格是有意义的操作虚拟
由于以下原因:给定类 Base 和 Derived使用重载引用限定操作 rqOp((以及一个名为 op(( 的非引用限定:
class Base{
public:
virtual ~Base() = default;
virtual
void rqOp() &&;
virtual void rqOp() &;
virtual void op();
};
class Derived : public Base{
public:
//virtual
void rqOp() &&; //override;
virtual void rqOp() & override;
virtual void op() override;
};
和一个重载函数:
void callOperationF(Base& b){
cout << "callOperationF(Base& b)" << endl;
cout << "b.rqOp();" << endl;
b.rqOp();
}
void callOperationF(Base&& b){
cout << "callOperationF(Base&& b)" << endl;
cout << "b.rqOp();" << endl;
b.rqOp();
cout << "std::forward<Base&&>(b).rqOp();" << endl;
std::forward<Base&&>(b).rqOp();
cout << "std::forward<Base&&>(b).op();" << endl;
std::forward<Base&&>(b).op();
}
以及对该重载的一些调用:
cout << "== Derived d;" << endl;
Derived d;
cout << endl;
cout << "== callOperationF(d);" << endl;
callOperationF(d);
cout << endl;
cout << "== callOperationF(Derived());" << endl;
callOperationF(Derived());
结果为输出:
== Derived d;
== callOperationF(d);
callOperationF(Base& b)
b.rqOp();
Derived::rqOp() &
== callOperationF(Derived());
callOperationF(Base&& b)
b.rqOp();
Derived::rqOp() & ===> 1
std::forward<Base&&>(b).rqOp();
Derived::rqOp() && ===> 2
std::forward<Base&&>(b).op();
Derived::op()
如我们所见,调用 RValue 引用合格操作 (rqOp(( &&(,我们需要使用 forward<.。>在 ===> 1 不合格的 RValue 被称为!因为 b 是一个 LValue 表达式。在 ===> 2 与 std::forward<..>正确的方法被称为,也
非引用限定操作 (OP((( 为正确调用 std::转发<...>。如果我们更改接口和重载 op(( 引用合格,它仍然会调用正确的方法,RValue 参考质量化一个。
使用模板化函数,如下所示:
template<class T>
void callOperationT(T&& t){
cout << "callOperationT(T&& t)" << endl;
cout << "t.rqOp()" << endl;
t.rqOp();
cout << "std::forward<T>(t).rqOp();" << endl;
std::forward<T>(t).rqOp();
cout << "std::forward<T>(t).op();" << endl;
std::forward<T>(t).op();
}
以及对此函数的一些调用,上面是 Derived d:
cout << endl;
cout << "== callOperationT(d);" << endl;
callOperationT(d);
cout << endl;
cout << "== Base& bRef = d;" << endl;
Base& bRef = d;
cout << "== callOperationT(move(bRef));" << endl;
callOperationT(move(bRef));
cout << endl;
cout << "== callOperationT(Derived());" << endl;
callOperationT(Derived());
结果为输出:
== callOperationT(d);
callOperationT(T&& t)
t.rqOp()
Derived::rqOp() &
std::forward<T>(t).rqOp();
Derived::rqOp() &
std::forward<T>(t).op();
Derived::op()
== Base& bRef = d;
== callOperationT(move(bRef));
callOperationT(T&& t)
t.rqOp()
Derived::rqOp() &
std::forward<T>(t).rqOp();
Derived::rqOp() && ===> 3
std::forward<T>(t).op();
Derived::op()
== callOperationT(Derived());
callOperationT(T&& t)
t.rqOp()
Derived::rqOp() &
std::forward<T>(t).rqOp();
Derived::rqOp() &&
std::forward<T>(t).op();
Derived::op()
具有相同的发现:调用RValue引用合格操作 (rqOp(( &&(,我们需要使用 forward<.。>在 ===> 3 Base::rqOp(( && 将被调用,如果 rqOp不是虚拟的。
谢谢!
我无法想象,因为该操作仅适用于临时对象
不一定。右值引用限定函数要求将对象绑定到右值引用。也就是说,你可以有一个函数,它返回对Base
的右值引用,但其动态类型Derived
:
struct Base {
virtual void f() && { std::cout << "Basen"; };
virtual ~Base() = default;
};
struct Derived : Base
{
void f() && override { std::cout << "Derivedn"; }
} child;
Base&& Get() {
return std::move(child);
}
int main() {
Get().f(); // Derived
}
我使用它的地方是在派生类实现的基类中创建一个unique_ptr
复制或移动函数:
class Base {
... whatever else
virtual std::unique_ptr<Base> mkuniq() && = 0;
virtual std::unique_ptr<Base> mkuniq() const & = 0;
class Derived : public Base
...
std::unique_ptr<Base> mkuniq() && { return std::make_unique<Derived>(std::move(*this)); }
std::unique_ptr<Base> mkuniq() const & { return std::make_unique<Derived>(*this); }
这允许我编写其他函数,这些函数将Base &&
作为一种要求,并在需要时在某个时候变成unique_ptr<Base>
。 然后可以使用未命名的临时Derived
调用所述函数。 当然,需要对 std::move
进行大量调用才能将命名的右值引用重新转换为未命名的右值重新围栏,但在处理右值引用时这是意料之中的。
- 虚拟决赛作为安全
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 如何在C++中获得"静态纯虚拟"功能?
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 大小虚拟继承中的派生类
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- std::is_trivially_copyable_v 关于虚拟功能
- 删除C++继承中虚拟类成员的代码重复
- 子类地址等于虚拟基类地址?
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 用于创建/注册虚拟存储设备的 IOKit 驱动程序
- 声明 RValue 方法(例如 void operation() 和 &;) 虚拟 C++1x )是否有意义