【问题标题】:defining private variables/properties in c++ class在 C++ 类中定义私有变量/属性
【发布时间】:2015-10-20 07:13:14
【问题描述】:

所以我发现了一些与在类中定义私有变量有关的事情。

目前,我的 Apple.h 文件如下所示:

#ifndef Apples_h
#define Apples_h

class Apples {
    public:
        Apples();
        void eat();
        void peel();
        void slice();

    private:
        int _seeds;
        String _type; // originally int by mistake
};

#endif

我的 Apple.cpp 文件如下所示:

#include "Apples.h"

int _seeds = 0; // default
String _type = 0; // default

Apples::Apples(){
    _seeds = 5000;
    _type = "notYummy";
}

// pretend all the public methods are implemented and are fine (no issues with them)

这实际上工作正常:我在我的头文件和 .cpp 文件中定义了一个私有属性 _seeds。

当我在其他地方定义属性 _seeds 时出现问题,比如在父类/主文件中。

然后它抱怨它有多个定义。对我来说,这有点奇怪,因为我认为 Apple.cpp 中的 _seeds 属性应该是私有的(因此是未知的),但它以某种方式将其拾取并在另一个文件中发生冲突。

我找了一个制作类的例子,他们没有在 .cpp 文件中定义类属性,而只是在头文件中定义了它,它似乎神奇地在 .cpp 中创建了这些私有属性文件(它们没有在 .cpp 文件的任何地方定义)。

我的“最接近”的语言可能是 Java,我在类实现文件中定义了所有类变量/属性,所以我有点困惑。

谁能确认一下:

  1. c/c++ 不是这种情况,您应该只在头文件中定义私有属性。

  2. 类 .cpp 文件中的任何变量/属性都是“全局命名空间”中的某种方式,它们可能会在其他文件中发生冲突。

如果第二点为真,是否可以通过在另一个类/文件中调用 _seeds 来实际访问它们?

(可能没关系,因为我认为这只是语言问题,但这是 arduino 的代码。)

【问题讨论】:

  • 这听起来不可能。类中的属性仅限于类。你能发布你的代码吗?
  • TL;DR:_type 应该是 int 还是 string
  • 请不要在变量名前加上下划线 - Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace
  • 嗯,是的,哎呀。 int 应该是一个字符串。但这不是问题所在。 >.> 嗯,我以为私有属性使用下划线是一种惯例?你是说带下划线的名字总是在全局命名空间中?
  • @Constantin 它们只保留在全局命名空间中。

标签: c++ class


【解决方案1】:

如果你在类之外编写它们,你正在新定义两个全局变量:

int _seeds = 0; // default
String _type = 0; // default

你只需要像你一样初始化ctor中的非静态成员变量。

【讨论】:

  • 在“ctor”中?如果这意味着 .cpp 文件,那么我猜第 1 点是正确的:仅在标头中定义,仅在 .cpp 文件中初始化?
  • 哦,“构造函数”。直到几分钟后才想到要查看它。 =/
  • @mitim 成员变量在类定义中定义,在类范围内使用(初始化),包括成员函数(和构造函数)。无论如何,您不能直接在全局范围内使用它们。
  • 好的。抱歉,我仍然习惯于 java(我只有一个文件而不是两个文件)。我假设“类定义”是头文件,“类范围”是我的 cpp 文件。好像是这样的。谢谢。现在我有很多工作要做,以修复我在实际代码中的错误。 >.>
【解决方案2】:

必须在 C++ 中的一处声明类的所有属性和方法。传统的方法是在头文件中进行,因此包含该头文件的所有文件都可以使用该类(它们需要完整的声明才能这样做!)。但是,.cpp 文件中的类声明也是有效的,但这样的类将仅在该 .cpp 文件中可用。

你的代码

int _seeds = 0; // default
String _type = 0; // default

与班级没有关系。这只是两个全局变量的定义。您可以设置非静态属性初始值的唯一方法是在构造函数中,您在问题中所做的方式看起来是正确的(假设您使用字符串类型而不是 int 声明 Apples::_type)。

【讨论】:

  • 对。其他人在答案中提到了它,但是您再次确认了它,我的第二点也是如此。谢谢。是的,你又是对的,int 应该是 _type 的字符串。一个错字,我通常会编辑我的问题并修复,但以后可能会让其他人想知道它指的是什么。
  • @mitim 我肯定会编辑问题中的属性类型并在评论中留下提示(例如String _type; // originally int by mistake)。一个好的问题应该解决一个问题,否则它会变得混乱。
猜你喜欢
  • 2013-11-27
  • 1970-01-01
  • 2021-11-22
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-12
相关资源
最近更新 更多