2017-10-05 72 views
1

的方法之间的差异请考虑构造的对象的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

回答

6

第一个和第二个对大多数类型都会做同样的事情。但是,对于具有接受std::initializer_list的构造函数的类型,第一个将更喜欢这个,第二个将更喜欢普通的构造函数。典型的例子是带有两个参数的std::vector - 它们是放入矢量的两个项目,还是一个重复计数的项目。

第三个版本根本不控制结构。正如Mateusz正确指出的,默认构造函数用于创建对象,然后通过赋值提供值。在许多类型中,一些参数只能在施工过程中设置,在赋值过程中不能更改,并且此方法根本不起作用。还要考虑必须在施工时绑定的引用和const成员,这些成员必须用其最终值构造,因为分配已禁用。

+3

第一个构造函数在没有初始化列表的情况下会使用列表初始化,这将防止任何缩小转换 - 如果成员的类型比参数 –

+1

更窄,则将无法编译尽管用户没有提到它,在没有收到任何参数的情况下讨论()vs {}可能会有所帮助,因为这对于聚合类型和基元是非常重要的区别。 –

+1

@NirFriedman:至少在ctor-initializer列表中,'x {}'和'x()'都会导致值初始化。也许你正在考虑语句,其中'X x {};'是带有支撑初始值设定项的对象声明,但是'X x();'是一个函数声明? –

4

在第三个例子着手完成,首先创建成员与默认的构造函数,然后复制分配。