首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >派生类的移动构造函数

派生类的移动构造函数
EN

Stack Overflow用户
提问于 2016-06-07 00:59:37
回答 1查看 2.5K关注 0票数 5

我有两门课:

代码语言:javascript
复制
template<typename T>
class base{
    T t;
public:
    base(base &&b): t(std::move(b.t)){}
};

template<typename T, typename T2>
class derived : protected base<T>{
    T2 t2;
public:
    derived(derived &&d): base<T>(std::move(d)), t2(std::move(d.t2)){}
};

我在derived move-constructor中移动整个base对象来初始化base部件,d变得无效,但我仍然需要它来使用它的部件进行t2初始化

做这样的事有可能吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-07 08:45:42

我想说的是,您的构造是正确的,除了一个小的语法错误,您需要在初始化程序列表中限定base<T>

代码语言:javascript
复制
derived(derived &&d): base<T>(std::move(d)), t2(std::move(d.t2)){}

首先,初始化顺序与初始化程序列表的顺序无关。n4296草案在12.6.2中提到初始化基地和成员class.base.init第13节

在非委托构造函数中,初始化按以下顺序进行: (13.1) -首先,而且仅对于最派生类(1.8)的构造函数,虚拟基类按照它们在基类有向无圈图的深度(首先左到右遍历)上出现的顺序进行初始化,其中“左到右”是派生类基类-说明符-列表中基类的出现顺序。(13.2)直接基类按照它们出现在基类说明符列表中的声明顺序进行初始化(不管mem初始化器的顺序如何)。(13.3)-然后,按照类定义中声明的顺序初始化非静态数据成员(同样不考虑mem初始化器的顺序)。(13.4)-最后,执行主体的复合-语句。 注意:声明顺序的任务是确保以初始化的相反顺序销毁基和子对象。-end注记

我们也有第7条或同一章规定:

每个mem初始化器执行的初始化构成一个完整表达式。mem初始化器中的任何表达式都作为执行初始化的完整表达式的一部分进行计算。

我的理解是,在derived类的move中,事情是按这个顺序发生的:

  • 基类的移动ctor称为。
    • 反过来,它为T调用移动ctor,有效地构造目标的t成员,并最终对源的t成员进行归零。

  • 调用T2对象的移动ctor --此时,未到达完整表达式的末尾,最终只销毁了源的t成员。
  • 在完整语句的末尾,源对象处于未定状态,不应再使用。
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37668952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档