在头文件中声明的c ++私有成员与在cpp文件中声明的静态变量

时间:2011-07-19 11:28:03

标签: c++

我有一个变量,我更喜欢在cpp文件而不是头文件中声明。它应该只能访问该类的对象。该变量应该为该类的每个对象都有一个单独的副本。继承是没有必要的。

通常,我只是在类定义中声明它。

A.H:

class A {
    private:
        int number;
}

但是,我可以这样做吗?

B.h:

class B {
    private:
        // nothing
}

B.cpp:

static int number;

6 个答案:

答案 0 :(得分:12)

不,如果你采用第二种方法,你将它变成一个静态变量,这意味着你不会为该类的每个对象都有一个不同的副本(它们都将共享该变量)。

无论哪种方式,如果它只应该由该类访问,它应该在类声明中,并且不应该是全局变量。通过使其成为静态全局变量,您将限制访问文件的范围,而不是类。作为良好的编程习惯,尽量使用尽可能少的全局变量。

答案 1 :(得分:8)

如果您的目标是隐藏仅查看您的头文件的客户的实施细节(为了保密或避免依赖于库内部),您正在寻找的设计模式是pimpl模式(“指向实现的指针”)。

myclass.h:

class MyClassImpl;

class MyClass
{
    public:
        MyClass();
        ~MyClass();
        int someFunc();

    private:
        MyClassImpl * pimpl;
}

myclass.cpp:

class MyClassImpl
{
    public:
        MyClassImpl();
        int someFunc();

    private:
        // whatever members you actually need
}

MyClass::MyClass()
{
    pimpl = new MyClassImpl();
}

MyClass::~MyClass()
{
    delete pimpl;
}

int MyClass::someFunc()
{
    return pimpl->someFunc();
}

// go on implementing MyClassImpl as you would have implemented MyClass

注意:此示例代码没有正确的复制语义。您可能希望使用一些智能指针,或者实现正确的复制构造函数/赋值运算符shenannigans。

答案 2 :(得分:5)

可以使用私有实现习惯用法隐藏cpp文件中的数据成员。

//a.hpp
struct AData;

class A
{
public:
  A();
private:
  AData* data_members;
};

//a.cpp
struct AData
{
   int number;
};

A::A(): data_members(new AData()) {}

不确定只用一个整数就可以获得回报。但这可以用来减少编译时间:您可以随意修改A的“数据成员”和实现,而无需重新编译包括a.hpp的文件。

此外,更喜欢合适的智能指针而不是普通指针(具有合适的复制行为且可以用不完整的类型声明)。

答案 3 :(得分:1)

This variable should have a separate copy for every object of that class. 

保持静止不会让你实现这一点。它将是所有实例共享的一个副本。

如果您希望每个对象都拥有自己的number副本,那么您必须使其成为您班级的成员。

答案 4 :(得分:0)

如果要为类的每个对象创建单独的副本,则需要在头文件中声明它,或者在对象值和对象构造函数初始化的对象的值之间使用某种静态映射。

答案 5 :(得分:0)

如果希望变量与类对象关联,则必须在类中声明它。所有对象数据都应该在类中。 这称为封装。