简体   繁体   English

始终将C ++类成员定义为唯一指针;

[英]Consistently defining C++ class members as unique pointers;

In C++ it's common to see things such as: 在C ++中,常见的情况是:

Header of class C C类头

//== C.h ==//
#pragma once
#include "B.h"

class C
{
    B b;
};

Header of class B B类头

//== B.h ==//
#pragma once
#include "A.h"

class B
{
    A a;
};

Header of class A A类头

//== A.h ==//
#pragma once

class A
{

};

Because Ch includes Bh , and Bh includes Ah ; 因为Ch包括BhBh包括Ah ; Ch ends up knowing implementation details about Ah . Ch最后知道了有关Ah实现细节。 In this case the headers are included only three levels deep, but in large projects including one header can quickly lead to the inclusion of hundreds of additional headers. 在这种情况下,标头仅包含三层,但是在大型项目中,如果包含一个标头,很快就会导致包含数百个其他标头。 Also resulting in long compile times. 也导致较长的编译时间。

In C++ 11 I could declare the headers as following: 在C ++ 11中,我可以将标头声明如下:

Header of class C: C类标题:

//== C.h ==//
#pragma once
#include <memory>

// proto
class B;

class C
{
    std::unique_ptr<B> b;
};

Header of class B B类头

//== B.h ==//
#pragma once
#include <memory>

// proto
class A;

class B
{
    std::unique_ptr<A> a;
};

Header of class A A类头

//== A.h ==//
#pragma once

class A
{

};

When replacing all members (class, struct) with smart pointers, I can include Ch without having to know the implementation of class B. Every cpp file now only has to know about it's members, without having to know about the memory layout of it's members. 用智能指针替换所有成员(类,结构)时,我可以包含Ch而不必知道类B的实现。每个cpp文件现在只需要了解其成员,而不必了解其成员的内存布局。

My question would be: 我的问题是:

  • Is it good design practice (a good idea) to replace all class members, that are either class and struct, with unique pointers? 将唯一的指针替换为类和结构的所有类成员是否是一种好的设计实践(一个好主意)? Are their additional pro's or cons ? 他们的其他优点还是缺点?

Straight direct data members support copying by default, if their types support copying. 如果直接类型的直接数据成员的类型支持复制,则默认情况下支持复制。 And it's maximally efficient. 而且效率最高。 If one feels that it's worth it to trade that for shorter build time, then why use C++, why not instead (then) just use a language that leverages such tradeoff maximally, such as Java or C#. 如果有人觉得为了缩短构建时间而进行交易是值得的,那么为什么要使用C ++,为什么不(然后)只使用一种最大限度地利用这种权衡的语言,例如Java或C#呢。

In other words, it appears to be an ungood idea. 换句话说,这似乎不是一个好主意。

For shorter build times while still using C++, consider faster machine or build server park. 为了在仍使用C ++的同时缩短构建时间,请考虑使用更快的计算机或构建服务器暂存区。

It's not a good idea to replace all members with pointers, as it would add an extra layer of dereferencing. 用指针替换所有成员不是一个好主意,因为这会增加额外的解引用层。 A direct member is actually allocated within the containing object, so accessing it is only requires a fixed offset from the containing object's location. 直接成员实际上是在包含对象内分配的,因此访问它只需要相对于包含对象的位置有一个固定的偏移量。

If you hide everything behind pointers, you would need to access the pointer member, then dereference the pointer to access the data (which will be somewhere else in memory). 如果将所有内容都隐藏在指针后面,则需要访问该指针成员,然后取消对该指针的引用以访问数据(该数据将位于内存中的其他位置)。 It's a trivial overhead on an individual basis, but it would soon add up if the principle was expanded across an entire program. 从单个角度看,这是微不足道的开销,但是如果将原理扩展到整个程序中,这很快就会加起来。

Another issue to bear in mind is maintainability. 要记住的另一个问题是可维护性。 If you store everything via pointers then you need to manually including appropriate construction and copying. 如果通过指针存储所有内容,则需要手动进行适当的构造和复制。 That can lead to various problems on a large project, as it increases the likelihood of programmer error. 这可能会导致大型项目出现各种问题,因为这增加了程序员出错的可能性。 By contrast, the compiler does a lot of that automatically if you're using direct members. 相比之下,如果您使用直接成员,则编译器会自动执行很多操作。

An alternative that's worth looking-up is the PIMPL design pattern (Private Implementation, or Pointer to Implementation). 值得一提的替代方法是PIMPL设计模式(私有实现或实现的指针)。 It's essentially a way of hiding the private details of a class inside its source file, with a view to reducing header dependencies. 从本质上讲,这是一种将类的私有详细信息隐藏在其源文件中的方法,目的是减少头文件的依赖性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM