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

时间:2014-02-24 12:56:55

标签: c++ c++11 smart-pointers

在C ++中,通常会看到以下内容:

C类标题

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

class C
{
    B b;
};

B类标题

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

class B
{
    A a;
};

A类标题

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

class A
{

};

因为C.h包含B.hB.h包含A.h; C.h最终了解有关A.h的实施细节。在这种情况下,标题只包含三个级别,但在包含一个标题的大型项目中,很快就会包含数百个额外的标题。也导致编译时间过长。

在C ++ 11中,我可以将标题声明如下:

C类标题:

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

// proto
class B;

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

B类标题

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

// proto
class A;

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

A类标题

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

class A
{

};

当用智能指针替换所有成员(类,结构)时,我可以包含C.h,而不必知道类B的实现。每个cpp文件现在只需知道它的成员,而不必知道关于它成员的记忆布局。

我的问题是:

  • 使用唯一指针替换所有类成员(类和结构)是否是一个好的设计实践(一个好主意)?是他们的额外职业或缺点吗?

2 个答案:

答案 0 :(得分:4)

如果直接数据成员的类型支持复制,则直接数据成员默认支持复制。它的效率最高。如果有人觉得用更短的构建时间进行交易是值得的,那么为什么不使用C ++,为什么不使用C ++,那么只使用最大限度地利用这种权衡的语言,例如Java或C#。

换句话说,它似乎是一个不合时宜的想法。

为了在使用C ++的同时缩短构建时间,请考虑更快的机器或构建服务器停放。

答案 1 :(得分:1)

用指针替换所有成员并不是一个好主意,因为它会添加额外的解除引用层。直接成员实际上是在包含对象中分配的,因此访问它只需要与包含对象位置的固定偏移量。

如果隐藏指针后面的所有内容,则需要访问指针成员,然后取消引用指针以访问数据(这将在内存中的其他位置)。这在个人的基础上是一个微不足道的开销,但如果原则在整个计划中得到扩展,它很快就会加起来。

要记住的另一个问题是可维护性。如果您通过指针存储所有内容,则需要手动包含适当的构造和复制。这可能会导致大型项目出现各种问题,因为这会增加程序员错误的可能性。相比之下,如果您使用直接成员,编译器会自动执行大量操作。

值得查看的替代方案是PIMPL设计模式(私有实现或指向实现)。它本质上是一种将类的私有细节隐藏在其源文件中的方法,以减少标头依赖性。