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

c++ private member declared in header vs static variable declared in cpp file

本文关键字:声明 cpp 文件 变量 静态 c++ 成员      更新时间:2023-10-16

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

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

A.h:

class A {
    private:
        int number;
}

但是,我可以这样做吗?

B.h:

class B {
    private:
        // nothing
}

B.cpp:

static int number;

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

无论哪种方式,如果它应该只由该类访问,那么它应该在类声明中,而不应该是全局变量。通过将其设置为静态全局变量,可以将访问权限仅限于文件的范围,而不是类。作为一种良好的编程实践,请尝试使用尽可能少的全局变量。

如果您的目标是向只看到您的头文件的客户隐藏实现细节(要么是为了保密,要么是为了避免对库内部的依赖(,那么您要寻找的设计模式就是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

小心:此示例代码没有正确的复制语义。您可能需要使用一些智能指针,或者实现正确的复制构造函数/赋值运算符恶作剧。

使用私有实现习惯用法可以隐藏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的"数据成员"和实现,而不必重新编译包括.hpp.在内的文件

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

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

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

如果您希望每个对象都有自己的number副本,那么您必须将其作为类的成员。

如果您希望类的每个对象都有一个单独的副本,您需要在头文件中声明它,或者在对象值和由对象构造函数初始化的对象值之间有某种静态映射。

如果希望变量与类对象相关联,则必须在类内部声明。所有对象数据都应该在类内。这就是所谓的封装。