C ++当全局变量不合适时保持计数

时间:2014-06-17 10:10:34

标签: c++ global-variables forward-declaration

我需要协调和向源自特定GrandParent对象的对象实例发出唯一的顺序数字标识符(1,2,3 ...等)。

我正在使用Microsoft编译器创建一个C ++ DLL,并且所有变量都封装在对象中;在这种情况下,全局变量不是一个选项,实际上是在这个项目中被设计出来的。

我已经尝试过以下方式解决问题,并发现通过前向声明无法访问另一个对象的成员函数(NB代码来说明我正在尝试实现的内容,它将无法编译,因为不正确地使用前向声明来访问成员函数):

GrandParent类:

//GrandParent
class GrandParent
{
public GrandParent(){}

int addParent()
{
Parent *par = new Parent(this);
return 0;
}

int incrementGrandChildIDNumber()
{
return grandChildIDNumber +=1;//increment
}

private:
int grandChildIdNumber;//keep count.  This NEEDS to be encapsulated. Cannot be a
 //global variable as there will be multiple instances of GrandParent each counting
 //and labeling it's own grand children.
};

家长班:

//Parent
class GrandParent;//forward declaration
class Parent
{
public Parent(GrandParent *ptrToGrandParent): ptr2GP(ptrToGrandParent){}

addGrandChild()
{
id = ptr2GP->incrementGrandChildIDNumber();//but forward declaration does not
    //give access to GrandParent member functions, right??
GrandChild grndChld = new GrandChild(id);
return 0;
}

private:
int id;
GrandParent *ptr2GP;
};

GrandChild班:

//GrandChild
 class GrandChild
{
 public:
    GrandChild(const int &id):idNumber(id){}

 private:
int idNumber;
};

我已经简化了问题,实际上每个类都要长得多,并在自己的头文件中定义。

我的问题是:如果前向声明不起作用且全局变量不适合此项目,还有哪些其他选项可用于协调ID号与GrandChild对象的发布?

2 个答案:

答案 0 :(得分:2)

在不同文件中分隔类定义和声明并使用静态变量:

// GrandParent.hh
#ifndef _GrandParent_
#define _GrandParent_

class Parent;

class GrandParent
{
  public:
    GrandParent();

    Parent * addParent();

    int incrementGrandChildIDNumber();

  private:
    static int grandChildIdNumber;
};

#endif


// GrandParent.cpp
#include "GrandParent.hh"
#include "Parent.hh"

int GrandParent::grandChildIdNumber = 0;

GrandParent::GrandParent()
{
}

Parent * GrandParent::addParent()
{
  Parent * par = new Parent(this);
  return par;
}

int GrandParent::incrementGrandChildIDNumber()
{
  return grandChildIdNumber++;
}

// Parent.hh
#ifndef _Parent_hh_
#define _Parent_hh_

class GrandParent;//forward declaration
class GrandChild;

class Parent
{
  public:
    Parent(GrandParent *ptrToGrandParent);

    GrandChild * addGrandChild();

  private:
    int id;
    GrandParent * ptr2GP;
};
#endif

// Parent.cpp
#include "Parent.hh"

#include "GrandParent.hh"
#include "GrandChild.hh"

Parent::Parent(GrandParent * ptrToGrandParent) : 
  ptr2GP(ptrToGrandParent)
{
}

GrandChild * Parent::addGrandChild()
{
  id = ptr2GP->incrementGrandChildIDNumber();
  GrandChild * grndChld = new GrandChild(id);
  return grndChld;
}


// GrandChild.hh
#ifndef _GrandChild_hh_
#define _GrandChild_hh_

class GrandChild
{
  public:
    GrandChild(int id);

  private:
    int idNumber;
};

#endif

// GrandChild.cpp
#include "GrandChild.hh"

GrandChild::GrandChild(int id) : 
  idNumber(id)
{
}

从主要使用它们:

#include "GrandParent.hh"
#include "Parent.hh"
#include "GrandChild.hh"

int main(int argc, char ** argv)
{
  GrandParent grandPa;

  Parent * parent1 = grandPa.addParent();
  Parent * parent2 = grandPa.addParent();

  GrandChild * gChild1_1 = parent1->addGrandChild();
  GrandChild * gChild1_2 = parent1->addGrandChild();

  GrandChild * gChild2_1 = parent2->addGrandChild();
  GrandChild * gChild2_2 = parent2->addGrandChild();
}

答案 1 :(得分:0)

拥有一个具有生成唯一标识符功能的单例类。 (这可以基于计数器顺序排列,也可以基于您喜欢的任何其他方案。)

或者,这可以只是基类中的函数,它基于静态计数器返回唯一的id。您甚至可以将它放在基类构造函数中。