C++通过对构造函数的引用传递.成员将是一个完整的私人副本

C++ pass by reference to constructor. Will member be a full private copy?

本文关键字:一个 副本 构造函数 引用 C++ 成员      更新时间:2023-10-16

在C++中,我有一个接受descriptor类对象的构造函数。这个班最近规模越来越大,我需要更多地通过参考。如果我通过引用将其传递到下面的ctor中,那么在未声明为引用类型的情况下,该成员是否仍会创建自己的副本?

    descriptor taskedStats;
public:
    CWorkerThread(int ticketNumber, int threadNumber, descriptor taskedStats) :
        _pPaginatableForm(pPaginatableForm), ticketNumber(ticketNumber)
        , threadNumber(threadNumber), taskedStats(taskedStats) {}

    descriptor taskedStats;
public:
    CWorkerThread(int ticketNumber, int threadNumber, descriptor &taskedStats) :
        _pPaginatableForm(pPaginatableForm), ticketNumber(ticketNumber)
        , threadNumber(threadNumber), taskedStats(taskedStats) {}

您的构造函数将生成一个副本,不管怎样。如果您传递值,那么您可能会生成两个副本,但是编译器可能会优化掉其中一个副本。

不过,更好的选择是接受常量引用,即

CWorkerThread(int ticketNumber, int threadNumber, descriptor const& taskedStats) :
   _pPaginatableForm(pPaginatableForm), 
   _ticketNumber(ticketNumber), 
   _threadNumber(threadNumber), 
   _taskedStats(taskedStats) 
{} 

当然,一旦我们进入C++11的世界并移动构造函数,您就不需要制作任何副本,只要不再需要传入的那个。即使现在也有一些方法可以做到这一点,但需要在对象内部进行特殊的"黑客攻击",或者使用智能指针。

类成员被声明为对象,因此它是一个对象。

传递给构造函数的引用将用于初始化成员,使用其复制构造函数。

在可能的情况下,最好通过const参考;这表明构造函数不会修改参数,还允许您传递一个临时值。

参数从descriptor更改为descriptor&仍将导致成员变量taskedStats从参数taskedStats复制(使用复制构造函数)。

为了避免复制,可以将成员变量taskedStats设为descriptor&,但这意味着参数taskedStats必须CWorkerThread对象的生存期内有效(在这种情况下,不将参数taskedStats设为const descriptor&将阻止临时对象的传递)。

编译器提供的默认或隐式副本构造函数生成所有成员的浅层副本,并具有以下签名:

descriptor(const descriptor &other);

因此,传递对描述符的引用与尝试(用C语言来说)传递副本没有什么不同——它们实际上都只是通过引用传递的。

如果成员被声明为引用类型,那么,就像指针一样,它的类型在上面的隐式复制构造函数中不匹配,并且将执行引用赋值,从而使在每个对象中创建本地副本的任何尝试都无效。

相关文章: