C++ 如何从全局对象中的成员对象访问全局对象

C++ How to access a Global Object from Member Objects within the Global Object

本文关键字:对象 全局 成员对象 访问 C++      更新时间:2023-10-16

G'day,

使用 C++,我希望有一个全局对象,其中包含多个公共成员对象,这些对象

可以"通过"全局对象访问,同时成员对象中的代码应该能够通过将其作为全局对象访问来调用全局对象中的方法(即无需将对全局对象的特定引用传递到成员对象中(。

我认为这将非常简单,按照下面的简化示例代码的行,但它不会编译。 在 IDE 中,在查看头文件时,我收到"重新定义全局对象/成员对象"和"未知类型名称"警告(尽管每个头文件中有"杂注一次"? 当我编译代码时,编译器报告"全局对象/成员对象未定义"错误。

我想我有某种循环引用问题,尽管老实说我真的不明白为什么,因为虽然全局对象包含对成员对象的引用,但成员对象不包含对全局对象的引用,因为我打算他们以与任何其他代码直接从 main 函数访问它的方式访问全局对象一样......? 通过在 main 函数外部声明全局对象然后在 MemberObject 头文件中将其引用为外部来使全局对象全局不会这样做,还是我在这里弄错了?

我知道人们对全局对象的邪恶有强烈的看法,但我相信在某些情况下它们是合适的,特别是在资源有限的嵌入式系统中,它们本质上是"启动"而不是"关闭"(或者至少不要以受控的方式关闭 - 电源只是关闭(。 所以我想知道我正在尝试做的事情如何才能发挥作用,或者如果不能,我想了解为什么不这样做。

我将不胜感激任何人可能提供的任何指导,谢谢。

GlobalObject.h

#pragma once
#include "MemberObject.h"
class GlobalObject
{
  private:
    int               Data;
    int               Total;
  public:
    GlobalObject();
    MemberObject      MO;
    int               GetData(void);
    void              SetData(int NewData);
    int               GetTotal(void);
    void              SetTotal(int NewTotal);
};

全局对象.cpp

#include "GlobalObject.h"
GlobalObject::GlobalObject() : MO()       { Data = 0; Total = 0; }
int  GlobalObject::GetData(void)          { return Data; }
void GlobalObject::SetData(int NewData)   { Data = NewData; }
int  GlobalObject::GetTotal(void)         { return Total; }
void GlobalObject::SetTotal(int NewTotal) { Total = NewTotal; }

MemberObject.h

#pragma once
#include "GlobalObject.h"
extern GlobalObject GO;
class MemberObject
{
  private:
    int               Data;
  public:
    MemberObject();
    int               GetData(void);
    void              SetData(int NewData);
    void              SetGlobalTotal(void);
};

成员对象.cpp

#include "MemberObject.h"
MemberObject::MemberObject()              { Data = 0; }
int  MemberObject::GetData(void)          { return Data; }
void MemberObject::SetData(int NewData)   { Data = NewData; }
void MemberObject::SetGlobalTotal(void)   { GO.SetTotal(GO.GetData() + Data); }

主.cpp

#include "GlobalObject.h"
GlobalObject GO;
int main(void)
{
  GO.SetData(1000);
  GO.MO.SetData(2000);
  GO.MO.SetGlobalTotal();
}
这是

您在设计类时应尽量避免的事情。

如果全局对象是单例,一种选择是对该对象的全局引用,然后每个人都可以通过该引用进入。(这对于日志记录框架、资源池等内容有些常见。特雷弗·希基(Trevor Hickey(的回答使用了这个选项。

唯一的另一种方法是让子对象明确知道父对象:MemberObject构造函数可以接受对作为其父级的GlobalObject的引用。 (不要使用指针,因为这会导致三法则问题(

似乎有什么问题?

struct Member{
  void method(){}
};
struct Global{
  Member member;
};
//global instance
Global global;
int main(){
  global.member.method();
}
使用 C++,我希望有一个全局对象,其中包含多个公共成员对象,这些对象

可以"通过"全局对象访问,同时成员对象中的代码应该能够通过将其作为全局对象访问来调用全局对象中的方法(即无需将对全局对象的特定引用传递到成员对象中(。

虽然您可以这样做,但它指出了设计中可能存在的缺陷。理想情况下,全局对象的成员对象不应依赖于全局对象来完成其工作。我建议退后一步,重新考虑你的设计。

我能给出的最简单的类比是,链表的节点不依赖于链表来很好地定义并完成它们的工作。另一方面,链接列表依赖于节点的详细信息来完成其工作。