我对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
答案 0 :(得分:20)
让我们一步一步改进您的代码。我将解释我在每一步所做的事情。
第1步,这不是Java。您不需要为每个成员指定公共。 public:
之后的所有内容都是公开的,直到您指定其他内容(protected
或private
)。我在课后也提到了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:”是奇怪的,你只需要编写一次。