如何创建类的静态对象成员?

时间:2009-08-29 11:25:53

标签: c++

我对c ++很新,特别是在它的技术方面。我的问题是,如何创建类本身的静态对象成员。我的意思是我在类中声明了一个静态成员对象。例如:

CFoo:CFoo *pFoo[2] = {0};

class CFoo
{
   public: static CFoo *pFoo[2];
   public: CFoo(int a);
   public: CFoo *getFoo();
};

现在问题是,如何创建pFoo,就像我想创建两个静态对象pFoo,

pFoo[0] = new CFoo(0);
pFoo[1] = new CFoo(1);

这样我就可以使用getFoo方法返回一个pFoo,比如

CFoo *getFoo()
{
   return pFoo[0]; //or pFoo(1);
}

非常感谢你们。希望我的问题很清楚。

提前再次感谢。 -sasayins

4 个答案:

答案 0 :(得分:20)

让我们一步一步改进您的代码。我将解释我在每一步所做的事情。

第1步,这不是Java。您不需要为每个成员指定公共。 public:之后的所有内容都是公开的,直到您指定其他内容(protectedprivate)。我在课后也提到了pFoo的定义。在声明变量之前,您无法定义变量。

class CFoo
{
   public: 
      static CFoo *pFoo[2];
      CFoo(int a);
      CFoo *getFoo();
};

CFoo* CFoo::pFoo[2] = {0};

步骤2,pFoo可能不应该公开,如果你有一个getFoo成员函数。让我们强制接口到类而不是暴露内部数据。

class CFoo
{
   public: 
      CFoo(int a);
      CFoo *getFoo();

   private:
      static CFoo *pFoo[2];
};

CFoo* CFoo::pFoo[2] = {0};

步骤3,您可以通过指针返回,而无需使用new。我已经编写了很多年的C ++代码,我必须查看你为静态成员变量创建的内存delete。找出它是不值得的麻烦,所以让我们把它们分配到堆栈上。另外,让我们通过 const 指针返回它们,以防止用户意外修改两个static CFoo对象。

class CFoo
{
   public: 
      CFoo(int a);
      const CFoo *getFoo();

   private:
      static CFoo foos[2];
};

CFoo CFoo::foos[2] = {CFoo(0), CFoo(1)};

然后getFoo的实施变为:

const CFoo * CFoo::getFoo()
{
   return &foos[0];  // or &foos[1]
}

IIRC,第一次创建foos对象时将分配静态成员CFoo。所以,这段代码......

CFoo bar;
const CFoo *baz = bar.getFoo();

......很安全。名为baz的指针将指向静态成员foos[0]

答案 1 :(得分:6)

你不需要这里的指针。事实上,他们可能不是一个好主意。

以下代码适用于我:

#include <iostream>

struct Foo {
    static Foo const foos[];

    Foo(int i) : i(i) { }

    int i;
};

Foo const Foo::foos[2] = { Foo(1), Foo(2) };

using namespace std;

int main() {
    cout << Foo::foos[0].i << endl;
}

(注意(为了保持演示简单)我已经创建了所有成员public,这可能不是你想要的东西。它与私人成员一样好。)

答案 2 :(得分:3)

要初始化数组,您应该写下:

CFoo* CFoo::pFoo [2] = { new CFoo(0), new CFoo(1) };

不要释放以这种方式分配的内存。

答案 3 :(得分:2)

有几种方法可以做到这一点。一个就是继续做你正在做的事情并像这样初始化pFoo数组

// In source file (not header)
CFoo* CFoo::pFoo[2] = {new CFoo(1), new CFoo(2)};

但我建议将它们包装在这样的存取器中:

// In header
class CFoo 
{
public:
  CFoo(int a);
  CFoo* getFoo1() const;
  CFoo* getFoo2() const;

private:
  static CFoo* getFoo(int n);
};

// In source file

CFoo::CFoo(int a)
{
 // Constructor implementation
}

CFoo* CFoo::getFoo1() const
{
  return getFoo(1);
}

CFoo* CFoo::getFoo2() const
{
  return getFoo(2);
}

CFoo* CFoo::getFoo(int n)
{
  static CFoo* pFoo[2] = {new Foo(1), new Foo(2)}; 
  return pFoo[n];
}

主要原因是这绕过了静态初始化命令fiasco。当你在一个类中有一个静态变量时,它在初始化时有点不确定,这是危险的,特别是当变量是公共的时。在访问器中进行包装意味着在首次调用访问器时将初始化变量,因此在尝试使用它之前,您将知道它已初始化。如果它暂时不使用或根本没有使用,你可以获得延迟初始化的好处。

上面的代码不是线程安全的,但我怀疑你在这里使用线程。

此外,您应该检查您的编码风格。使用C前缀类是一种有点过时的做法,在每个公共函数之前放置“public:”是奇怪的,你只需要编写一次。