-2

在 C++ 中,我有一个接受 class 对象的构造函数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) {}
4

4 回答 4

2

您的构造函数将制作一个副本,无论如何。如果您按值传递,那么您可能会制作 2 个副本,但是编译器可能会优化掉其中一个。

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

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

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

于 2012-02-06T13:53:26.657 回答
2

类成员被声明为一个对象,所以它是一个对象。

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

可以的话最好通过const引用传递;这清楚地表明构造函数不会修改参数,并且还允许您传递临时值。

于 2012-02-06T13:54:35.287 回答
1

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

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

于 2012-02-06T13:55:34.947 回答
0

编译器提供的默认或隐式复制构造函数对所有成员进行浅拷贝,并具有以下签名:

descriptor(const descriptor &other);

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

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

于 2012-02-06T13:45:53.933 回答