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

时间:2016-02-01 02:25:38

标签: c++

G'天,

使用C ++,我希望有一个全局对象,它包含几个可以通过全局对象访问的公共成员对象,同时成员对象中的代码应该能够调用全局对象通过将其作为全局对象访问(即,不将对全局对象的特定引用传递给成员对象)。

我认为这将是非常简单的,与我下面的简化示例代码一致,但它不会编译。在IDE中,在查看头文件时,我得到“重新定义GlobalObject / MemberObject”和“未知类型名称”#34;警告(尽管每个头文件中都有“pragma once”)。当我编译代码时,编译器报告“GlobalObject / MemberObject未定义”错误。

我想我有某种循环引用问题,但老实说我并不理解为什么,因为当全局对象包含对成员对象的引用时,成员对象不能t包含对全局对象的引用,因为我打算以与任何其他代码直接从main函数访问它相同的方式访问全局对象...?通过在主函数之外声明它然后在MemberObject头文件中将其引用为外部来使GlobalObject全局化,或者我在这里弄错了吗?

我知道人们对全球物体的邪恶有强烈的看法,但我相信在某些情况下它们是合适的,特别是在资源有限且基本上“启动”而从不“关闭”的嵌入式系统中(或者至少不以受控的方式关闭 - 电源刚刚关闭。所以我想知道我想要做什么可以工作,或者如果不能,我想知道为什么不。

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

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);
};

GlobalObject.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);
};

MemberObject.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); }

的main.cpp

#include "GlobalObject.h"

GlobalObject GO;

int main(void)
{
  GO.SetData(1000);
  GO.MO.SetData(2000);
  GO.MO.SetGlobalTotal();
}

3 个答案:

答案 0 :(得分:1)

在设计课程时,您应该尽量避免这种情况。

如果全局对象是单例,则一个选项是对该对象进行全局引用,然后每个人都可以通过该引用进入。 (这在日志记录框架,资源池等方面有些常见。)Trevor Hickey的答案使用了这个选项。

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

答案 1 :(得分:0)

似乎是什么问题?

struct Member{
  void method(){}
};

struct Global{
  Member member;
};

//global instance
Global global;

int main(){
  global.member.method();
}

答案 2 :(得分:0)

  

使用C ++,我希望有一个全局对象,它包含几个可以通过全局对象访问的公共成员对象,同时成员对象中的代码应该能够调用全局对象通过将其作为全局对象访问(即,不将对全局对象的特定引用传递给成员对象)。

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

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