【问题标题】:C++ Style Convention: Parameter Names within Class DeclarationC++ 样式约定:类声明中的参数名称
【发布时间】:2009-04-21 07:46:06
【问题描述】:

我是一个相当新的 C++ 程序员,我想听听支持和反对在类声明中命名参数的论点。


这是一个例子:

学生.h

#ifndef STUDENT_H_
#define STUDENT_H_

#include <string>

using namespace std;

class Student
{
    private:
        string name;
        unsigned int age;
        float height, GPA;

    public:
        Student(string, unsigned int, float, float);

        void setAge(unsigned int);
};

#endif /*STUDENT_H_*/

对比

#ifndef STUDENT_H_
#define STUDENT_H_

#include <string>

class Student
{
    private:
        string name;
        unsigned int age;
        float height, GPA;

    public:
        Student(string name, unsigned int age, float height, float GPA);

        void setAge(unsigned int age);
};

#endif /*STUDENT_H_*/

Student.cpp

#include "Student.h"

Student::Student(   string name,
            unsigned int age,
            float height,
            float GPA) :

            name(name),
            age(age),
            height(height),
            GPA(GPA) {}

void Student::setAge(unsigned int age) { this -> age = age; }

我无法决定。一方面,我觉得在声明(.h)和定义(.cpp)中都给变量命名是多余的。特别是因为您必须担心更新两个地方的名称以使它们匹配。另一方面,如果没有名称,仅通过查看声明来确定参数对应的变量通常会令人困惑。

那么,你的想法是什么?

【问题讨论】:

  • 只使用intdouble,而不是unsigned intfloat。在unsigned int 的情况下,您可能正在尝试记录值约束,但不是 C++ 强制它提供了许多陷阱,即没有收益,但有很多不必要的痛苦。通常只在处理位级别或库函数强制使用的地方使用无符号类型。对于float,您可能正在尝试节省内存。除非你有数十亿学生,否则这是错误的。 :-) 干杯&hth。
  • @Alf P. Steinbach:有哪些陷阱?当浮点数足够时为什么要加倍?详细说明。

标签: c++ coding-style parameters naming-conventions


【解决方案1】:

在声明中使用参数名会好很多,并且使用好的参数名。这样,它们就可以用作功能文档。否则,您将不得不在标题中编写额外的 cmets,并且使用好的参数/变量名称总是比使用 cmets 更好。

例外:由于外部原因,函数必须具有特定签名,但参数并未实际使用。在这种情况下,您也不应该在实现中命名它们。

【讨论】:

  • 例外:当参数很明显或类型是自记录的,例如Point3D(T, T, T)Pair(Key, Value)都非常清晰。
【解决方案2】:

将名称放在两个地方,清晰是您在两个地方维护签名的任务所获得的奖励。

【讨论】:

    【解决方案3】:

    Intellisense/autocomplete/开发环境中的任何类似内容通常只会看到声明,并且只会将其显示为自动完成。因此,如果您不在声明中声明名称,用户将不会在自动完成中看到它们,除非他们去阅读源代码。这也许是可以忍受的,但不是很方便。

    【讨论】:

    • 哦,无论如何,我把名字放在了声明中。也许我的帖子不够清楚,但我试图找出支持或反对另外将名字放在标题中的理由。
    • 糟糕!刮那个。我在您的回答中阅读了“定义”而不是“声明”。感谢您提供信息。
    【解决方案4】:

    即使是多余的,我发现最好在两个地方都有参数名称。这通常是因为更改参数名称通常会产生语义后果。在标头中缺少它有助于搞砸文档(这是我倾向于放置大多数 cmets 即 API 规范的地方)并且在实现中缺少它会帮助我忘记为什么该特定参数具有如此奇怪的名称。

    我放弃参数名称的唯一一次是当我必须实现第三方库回调并且我没有使用其中一个参数时。即使那样我也会这样做:

     my_callback(int idx, Context* /*ctx*/)  { ...
    

    这样我就知道签名了。

    【讨论】:

      【解决方案5】:

      如果您将代码发布为带有关联 .h 文件的库,您的用户将永远不会看到定义,只会看到声明,这会给您自己增加额外的文档负担。

      【讨论】:

        【解决方案6】:

        一方面,我觉得它是 多余的变量命名 声明 (.h) 和 定义 (.cpp)。特别是从 你必须担心更新 在这两个地方的名字,使他们 匹配。

        您不需要名称来匹配字面意思。指定接口的头文件有点像一个不完美的合同(不完美是因为它不包含前置条件和后置条件,除非你在 cmets 中将它们写下来)和一个“调用者指南”。在 99% 的情况下,类的调用者会想知道参数 是什么。至少让他知道发生了什么事。因此,您必须选择一个对调用者有意义的参数名称。这不需要与 cpp 中的名称相同。然而这并不重要,因为我习惯于首先将函数签名从 .h 复制/粘贴到 .cpp 。对我来说,用 C++ 编程意味着这个手册部分。

        另一方面,没有名字,它 往往会让人难以确定 什么变量参数 仅通过查看 声明。

        这是一手好牌。

        【讨论】:

          【解决方案7】:

          我想这取决于您的变量类型的描述性。如果您的方法签名包含用于多种用途的类型,那么它很有用:

          double calculateTax(int, string);
          

          如果类型是描述性的,那么包含名称是多余的。

          Money calculateTax(Order, State);
          

          我不希望将名称保留在两个文件中。

          【讨论】:

            【解决方案8】:

            是的,.h 文件中的参数不需要命名。头文件应该代表一个接口,所以它不需要有不需要的细节。

            HTH

            【讨论】:

            • 似乎对您链接的问题的共识是不要对成员变量使用下划线,而我没有。虽然有些人可能会觉得它冗长烦人,但我倾向于使用“this”关键字,就像我在上面发布的示例中一样。我不确定你想用那个链接来说明什么。
            • True - “float, float” 不是接口。 “float height, float GPA”才是真正的界面。
            • 对不起,我删除了下划线链接。它是为其他人设计的:-) @MSalters:我同意参数名称增加了接口提供的含义,但恕我直言,依赖它并不是理想的方式。如果有人在标头和 impl 中以不同方式重命名它们怎么办?文件。会更加混乱。从维护的角度来看,我觉得将名称从标题中删除是有帮助的。
            • 完全不同意,接口不仅仅是函数签名,而是预期的含义:参数名称是接口的一部分。在一个地方更改名称而不在另一个地方更改名称是错误的,即使编译器不会标记它。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-02-08
            • 2014-05-31
            • 1970-01-01
            • 2017-05-05
            • 2011-01-04
            • 1970-01-01
            相关资源
            最近更新 更多