【问题标题】:Pointer vs variable in class类中的指针与变量
【发布时间】:2011-01-14 09:56:28
【问题描述】:

我知道它们有什么区别以及它们是如何工作的,但这个问题更多的是关于编码风格。

每当我编写代码时,我都会创建许多类,它们都有变量,其中一些是指针,一些是普通变量。如果成员持续时间与类一样长,我通常更喜欢变量而不是指针,但是我的代码变成这样:

engine->camera.somevar->x;
// vs
engine->camera->somevar->x;

我不喜欢中间的点。或者使用私有变量:

foo_.getName();
// vs
foo_->gatName();

我认为那个点在长代码中“消失”了。我发现 -> 在某些情况下更容易阅读。

我的问题是,即使变量将在构造函数中创建并在析构函数中删除,你是否使用指针?在这种情况下有什么风格建议吗?

附:我确实认为点在某些情况下看起来更好。

【问题讨论】:

    标签: c++ variables pointers coding-style


    【解决方案1】:

    首先,暴露成员变量是不好的形式。

    其次,你的类可能永远不应该使用容器指针。

    轻微推论:包含业务逻辑的类不应该有指针(因为这意味着它们还包含指针管理代码,指针管理代码应该留给没有业务逻辑但专门为管理指针而设计的类(智能指针和容器)。

    指针管理类(智能指针/容器)应设计为管理单个指针。管理多个任务比您预期的要困难得多,而且我还没有发现额外的复杂性得到回报的情况。

    最后,公共成员不应该暴露底层实现(即使通过 getter/setter,也不应该提供对成员的访问)。这将接口紧密绑定到实现。相反,您的公共接口应该提供一组可以在对象上执行的操作。即方法是verbs

    在 C++ 中很少看到指针。
    它们通常隐藏在其他类中。但是您应该习惯于混合使用->.,因为这完全取决于上下文以及您要传达的内容。只要代码干净可读,就没有太大关系。

    个人附录:

    我讨厌标识符末尾的 _ 它使 .消失foo_.getName() 我觉得像foo.getName() 看起来会好很多

    【讨论】:

    • 好吧,但是成员与智能指针(在实现代码中)呢?
    • @user396672:他们呢。智能指针只是一个与其他对象一样的对象。它的工作是管理单个指针。
    • 好吧,有些类有公共变量,我认为没有理由将它们设为私有。如果类的工作可能因无效使用它们而损坏,我只会制作私有变量。如果他们在课堂上只是为了使程序的结构更好 - 为什么不呢。例如引擎的例子。当我编写任何游戏时(有时我会制作糟糕的游戏。这很有趣),我会制作一个外部指针“引擎”,因为它被许多其他对象使用。该引擎通常包含公共范围内的相机之类的东西。我这样做是因为其他对象必须访问相机类并且它不能破坏引擎。
    • @Valdo:是的,在某些情况下,成员变量可以合法地公开(如结构包)。但;通常 variables 成员不应通过 public 公开,因为它会破坏封装。这是面向对象编程的一个重要原则。现在将成员公开不会破坏您的代码,它只会使长期更新或维护变得困难。
    【解决方案2】:

    如果“嵌入”结构与“父”结构具有完全相同的生命周期,并且没有在其他任何地方引用,我更喜欢将其作为成员,而不是使用指针。生成的代码效率稍高一些,因为它节省了对内存分配器的多次调用,并且避免了多次指针取消引用。

    它也更容易处理,因为指针相关错误的机会减少了。

    另一方面,如果嵌入结构极有可能在其他地方被引用,我更喜欢使用单独的结构和指针。这样一来,如果发现嵌入的结构需要从其父级中拉出,我就不必重构我的代码。

    编辑:

    我想这意味着我通常会选择指针替代 :-)

    编辑 2:

    是的,我的回答是假设您确实想要(或必须)在两者之间进行选择,即您编写 C 风格的代码。访问类成员的正确的面向对象方式是通过 get/set 函数。

    不过,我的 cmets 是否包含实际类实例或指向某个类实例的指针/引用可能仍然有效。

    【讨论】:

    • 成员,但是,可能会导致大对象,导致出现内存碎片问题
    【解决方案3】:

    您不应该做出选择,因为您发现“->”更容易阅读:) 使用成员变量通常会更好,因为指针不会出错。

    这就是说,使用成员变量会强制您公开您的实现,因此您必须使用引用。但是你必须在你的构造函数中初始化 then ,这并不总是可能的......

    一种解决方案是使用 std::auto_ptr 或 boost::scoped_ptr 或类似的智能指针。在那里,您将获得两种解决方案的优势,几乎没有缺点。

    my2c

    编辑:

    一些有用的链接:
    Article on std::auto_ptr
    boost::scoped_ptr
    Pimpl : private implementation

    【讨论】:

      【解决方案4】:

      理想情况下,您不应该使用任何一种:您应该使用 getter/setter 方法。对性能的影响很小(无论如何编译器可能会将其优化掉)。

      第二个考虑是使用指针通常是一个危险的想法,因为在某些时候你可能会搞砸它。

      如果这些都不让你烦恼,那么我想说剩下的就是个人喜好问题了。

      【讨论】:

      • getters/setters 是糟糕的设计,因为它暴露了实现,因此将你耦合到它(它的耦合比暴露变量少,但仍有很多不足之处)。
      • 例如,还有哪些未包含在本文中的内容? stackoverflow.com/questions/2747721/… 换句话说,为什么你觉得它们从来没有用过?
      • 永不言败。您链接的文章和链接的文章也详细介绍了该主题。但这归结为耦合。您的代码耦合得越紧密,维护和/或修改/升级就越困难。 Getter/Setter 引入了通常不需要的额外耦合。
      • 我同意你的观点,但问题是你给人的印象是永远不会。如果它不是“一般”需要的,那么在特定情况下需要它。我们没有足够的信息来判断 OP 的情况,只是说他认为他需要提供对成员变量的访问。在这种情况下,定义一个 API,其中“引擎”允许公共访问“相机”...
      猜你喜欢
      • 2021-11-11
      • 2011-08-04
      • 2019-06-17
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多