【问题标题】:Using Member Variables That Are Private c++使用私有 c++ 的成员变量
【发布时间】:2014-09-12 00:55:31
【问题描述】:

我添加了所有代码。

我面临的确切问题是,当我在game.h 文件中创建成员变量private 时,我在game.cpp 文件中收到一个错误,上面写着n p h 都是game.h 的私有成员。在Xcode

但是当我从命令行编译程序时,它编译得很好,没有错误。

我想了解我是否做错了什么,或者我这样做是否符合标准?

这是 main.cpp

#include "game.h"


int main() {

   game g("Female", "Magic", true, 21, 5, 120);

    std::cout << "These are the things every game needs to be a game" << '\n';

    std::cout << g << '\n';

    return 0;
}

游戏.cpp

#include <iostream>

#include "game.h"

std::ostream& operator<<(std::ostream& s, const game& g) {
    return s << &g.n << ' ' << &g.p  << ' ' <<  &g.h;
}

这是我的复合类

#include <iostream>

#include "npc.h"
#include "pc.h"
#include "health.h"

class game {
private:
    npc n;
    pc p;
    health h;

public:
    game(const npc& init_n, const pc& init_p, const health& init_h):
    n(init_n),
    p(init_p),
    h(init_h)
    {}


    game(std::string gen, std::string abil, bool use, int lvl, int h, int arm) :
    n(gen, abil),
    p(use, lvl),
    h(h, arm)
    {
    }

 friend std::ostream& operator<<(std::ostream& s, const game& g) {
         g.n.output(s);
         g.p.output(s);
         g.h.output(s);
        return s;
 }

     npc get_n() { return n; }
     pc get_p() { return p; }
     health get_h() { return h; }

     void set_n(npc init_n) { n = init_n; }
     void set_p(pc init_p) { p = init_p ; }
     void set_h(health init_h) { h = init_h; }
};

这是一个类

#include <iostream>

class health {
private:
    int hp;
    int armor;

public:
    health(int init_hp, int init_armor) :
    hp(init_hp),
    armor(init_armor)
    {
    }

public:
    void output(std::ostream& s) const { s << "Characters have this amount of hit points "<< hp << " and an armor rating of " << armor << "\n";  }

    };

这是一个类

class pc {
private:
    bool user;
    int level;

public:
    pc(bool init_user, int init_level) :
    user(init_user),
    level(init_level)
    {
    }

public:
    void output(std::ostream& s) const { s << "A player character has at least "<< user << " user and a level of " << level << '\n';  }

};

这是一个类

#include <iostream>

class npc {
private:
    std::string gender;
    std::string ability;

public:
    npc(std::string init_gender, std::string init_ability) :
    gender(init_gender),
    ability(init_ability)
    {
    }

public:
  void output(std::ostream& s) const { s << "A non player character has a gender of "<< gender << " and an ability of " << ability << '\n';  }

};

【问题讨论】:

  • ...你在使用你的getter和setter吗? C++ 不会自动将属性访问转换为 getter 或 setter 调用。
  • 显示您遇到问题的代码
  • 你的 setter 中的分配是错误的。
  • 离题,但最好将 getter 标记为 const;例如:npc get_n() const { return n; }
  • 我正在显示我遇到问题的代码。是的,我重新排列了 getter 和 setter。仅当我将其更改为 public 时仍然有效

标签: c++


【解决方案1】:

您犯了几个错误 - 一个错字是您的问题的原因。 该函数不允许访问这些成员,因为它不是类的朋友。 朋友是(正确)std::ostream&amp; operator&lt;&lt;(std::ostream&amp; s, const game&amp; g) 当您定义函数 std::ostream&amp; operator&lt;&lt;(std::ostream&amp; s, const game g) 时,请注意缺少的 & 符号。

此外,您的访问器应该是 const,并返回一个 const 引用。 即,

 npc const& get_n() const { return n; }
 pc const& get_p() const { return p; }
 health const& get_h() const { return h; }

您的操纵器更改了错误的变量!您更改了传递给函数的那些而不是该类的成员....但是,为三个私有成员添加直接操纵器是非常值得怀疑的。您必须将您的类视为一些抽象对象并定义适用于该对象的运算符。如果您只是直接访问它的所有成员,那么在使用带有私有成员的类背后几乎没有留下面向对象的想法(但这仍然比将它们公开好十倍!)

最后,只是一个编码风格提示。通常的做法是为自定义类(即类 Game)使用 CamelCase 名称,并且您最好为私有成员添加前缀以将它们与函数参数区分开来。人们经常使用前缀m_。你真的应该使用完整的英文单词(不是缩写,更不用说单个字符)。

这会将您的代码变成...

class Game {
  private:
    Npc m_npc;
    Pc m_pc;
    Health m_health;

  public:
    Game(Npc const& npc, Pc const& pc, Health const& health) :
        m_npc(npc), m_pc(pc), m_health(health) { }

等等

【讨论】:

  • 感谢您的回答。但这并不能解决我的问题。虽然有很多很好的信息。事实上,我发现通过在 osx 中从终端编译,程序运行良好。但由于某种原因,它不会在 xcode 中编译,并且当它们是私有的时无法访问这些变量。我意识到我在game&amp; 上没有&amp;,因为它说重新定义
  • 你的操作员friend std::ostream& operator<<(std::ostream& os, Game const& game) { return os << game.m_npc << ' ' << game.m_pc << ' ' << game.m_health; }。如果您仍然有编译错误,请提供完整的、可编译的测试代码 sn-p;我更正了您迄今为止发布的所有内容。
  • 我更新了我的代码以向您展示这一切。我拥有它的方式可以从命令行很好地编译,但 main.cpp 说 n p h 是 game.h 的私有成员。
  • 你改变的有两个操作符的实例删除 game.cpp 中的那个。更改之后,我可以编译并链接它(并运行它)。
  • 如果在从类游戏中定义的运算符
猜你喜欢
  • 2019-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 2011-04-04
  • 2023-04-08
  • 2015-04-16
相关资源
最近更新 更多