将成员变量作为类成员引用
在我的工作场所,我看到这种风格被广泛使用:-
In my place of work I see this style used extensively:-
#include <iostream>
using namespace std;
class A
{
public:
A(int& thing) : m_thing(thing) {}
void printit() { cout << m_thing << endl; }
protected:
const int& m_thing; //usually would be more complex object
};
int main(int argc, char* argv[])
{
int myint = 5;
A myA(myint);
myA.printit();
return 0;
}
有没有名字可以描述这个成语?我假设这是为了防止复制大型复杂对象可能产生的大量开销?
Is there a name to describe this idiom? I am assuming it is to prevent the possibly large overhead of copying a big complex object?
这通常是好的做法吗?这种方法有什么缺陷吗?
Is this generally good practice? Are there any pitfalls to this approach?
推荐答案
有没有名字可以描述这个成语?
Is there a name to describe this idiom?
在 UML 中,它被称为聚合.它与组合的不同之处在于成员对象不属于引用类所有.在 C++ 中,您可以通过引用或指针以两种不同的方式实现聚合.
In UML it is called aggregation. It differs from composition in that the member object is not owned by the referring class. In C++ you can implement aggregation in two different ways, through references or pointers.
我假设这是为了防止复制大型复杂对象可能产生的大量开销?
I am assuming it is to prevent the possibly large overhead of copying a big complex object?
不,这将是使用它的一个非常糟糕的理由.聚合的主要原因是包含对象不属于包含对象,因此它们的生命周期不受限制.特别是被引用的对象生命周期必须比引用的生命周期更长.它可能已经创建得更早,并且可能存在于容器的生命周期结束之后.除此之外,被引用对象的状态不受类控制,但可以从外部改变.如果引用不是 const
,则该类可以更改位于它之外的对象的状态.
No, that would be a really bad reason to use this. The main reason for aggregation is that the contained object is not owned by the containing object and thus their lifetimes are not bound. In particular the referenced object lifetime must outlive the referring one. It might have been created much earlier and might live beyond the end of the lifetime of the container. Besides that, the state of the referenced object is not controlled by the class, but can change externally. If the reference is not const
, then the class can change the state of an object that lives outside of it.
这通常是好的做法吗?这种方法有什么缺陷吗?
Is this generally good practice? Are there any pitfalls to this approach?
它是一种设计工具.在某些情况下,这将是一个好主意,在某些情况下则不是.最常见的陷阱是持有引用的对象的生命周期绝不能超过被引用对象的生命周期.如果封闭对象在引用的对象被销毁后使用引用,您将有未定义的行为.一般来说,最好选择组合而不是聚合,但如果您需要它,它与其他任何工具一样好.
It is a design tool. In some cases it will be a good idea, in some it won't. The most common pitfall is that the lifetime of the object holding the reference must never exceed the lifetime of the referenced object. If the enclosing object uses the reference after the referenced object was destroyed, you will have undefined behavior. In general it is better to prefer composition to aggregation, but if you need it, it is as good a tool as any other.
相关文章