什么是构造物体
问题描述:
的方法之间的差异请考虑构造的对象的3种方式:什么是构造物体
1)
LogTreeItem::LogTreeItem(const QList<QVariant>& data, LogTreeItem* parent) :
m_parentItem {parent}, m_itemData {data}
{
}
2)
LogTreeItem::LogTreeItem(const QList<QVariant>& data, LogTreeItem* parent) :
m_parentItem (parent), m_itemData (data)
{
}
3 )
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)
{
m_parentItem = parent;
m_itemData = data;
}
它们100%相等吗?如果不是,他们在哪里有区别?每种方法有哪些优势/劣势?
我猜测的拷贝赋值一些东西,移动的构造函数或现代C++ 11及以后的一些先进的东西在1例和2
答
第一个和第二个对大多数类型都会做同样的事情。但是,对于具有接受std::initializer_list
的构造函数的类型,第一个将更喜欢这个,第二个将更喜欢普通的构造函数。典型的例子是带有两个参数的std::vector
- 它们是放入矢量的两个项目,还是一个重复计数的项目。
第三个版本根本不控制结构。正如Mateusz正确指出的,默认构造函数用于创建对象,然后通过赋值提供值。在许多类型中,一些参数只能在施工过程中设置,在赋值过程中不能更改,并且此方法根本不起作用。还要考虑必须在施工时绑定的引用和const
成员,这些成员必须用其最终值构造,因为分配已禁用。
答
在第三个例子着手完成,首先创建成员与默认的构造函数,然后复制分配。
第一个构造函数在没有初始化列表的情况下会使用列表初始化,这将防止任何缩小转换 - 如果成员的类型比参数 –
更窄,则将无法编译尽管用户没有提到它,在没有收到任何参数的情况下讨论()vs {}可能会有所帮助,因为这对于聚合类型和基元是非常重要的区别。 –
@NirFriedman:至少在ctor-initializer列表中,'x {}'和'x()'都会导致值初始化。也许你正在考虑语句,其中'X x {};'是带有支撑初始值设定项的对象声明,但是'X x();'是一个函数声明? –