私有静态成员之间的区别以及将它们放在cpp文件中

时间:2014-11-24 18:57:47

标签: c++

假设我希望A类有一个变量和一个可用于所有实例的函数,但仅限于它们。
我有两种方法(或者更多?):

将它们作为私有静态成员:

class A {
    ...

    private:
        static int myInt;
        static void myMethod();

    ...
};

只需将它们放在cpp文件中:

// h file
class A {
    ...
};

// cpp file
static int myInt;
static void myFunction() { ... }

这两个选项在我看来都会很好,但除了与设计相关的论点外,有什么区别? 有没有比另一种更好的选择?
是否有任何性能或优化问题? 感谢。


修改

似乎我不够清楚,所以这里有一个更好的例子(留下旧的例子,以便之前的评论/答案都有意义):

第一个选项:

// h file
class A {
    public:
        A();
        ~A();

        void doSomething();

    private:
        static std::queue queue;
        static boost::mutex mutex;

        static void initQueue();
};

// cpp file

// let's assume this method can be called multiple times but only initiates the queue on the first call
void A::initQueue() {
    boost::unique_lock<boost::mutex> lock(A::mutex);
    ...
}

void A::A() {
    A::initQueue();
}

void A::doSomething() {
    // have full access to the A::queue/A::mutex
}

第二个选项:

// h file
class A {
    public:
        A();
        ~A();

        void doSomething();
};

// cpp file
static std::queue queue;
static boost::mutex mutex;

static void initQueue() {
    boost::unique_lock<boost::mutex> lock(Amutex);
    ...
}


void A::A() {
    initQueue();
}

void A::doSomething() {
    // have full access to the queue/mutex
}

至于能见度,我的意思是通过包括A.h我无法访问变量/函数,但只能从类A中访问。
我并不是说如何防范恶意代码等等。

2 个答案:

答案 0 :(得分:2)

私有成员是类的用户无法访问的实现细节。将它们暴露在头文件中会产生不必要的编译依赖性。例如,私有成员可能需要包括其他头文件,这会减慢包含标题的翻译单元的编译速度;更改头文件中的实现细节需要重新编译其所有用户。因此,最好只在头文件中公开用户可以直接使用的内容(公共API),并尽可能避免在公共API头中公开实现细节。

Herb Sutter在GotW #100: Compilation Firewalls中对此主题进行了彻底的处理。


您可以轻松地将所有非公共静态类成员移动到.cc文件和未命名的命名空间中。

非静态数据成员可以移动到Pimpl中或隐藏在抽象接口后面。 Pimpl的优势在于它不需要用户直接处理智能指针和工厂,也不会使用比非虚拟调用稍慢的虚拟调用。

隐藏数据成员实现的运行时成本是成员函数的实现必须在.cc中,以便在没有链接时代码生成的情况下无法内联对类API的调用。 / p>

答案 1 :(得分:0)

不同之处在于私有静态成员是类的一部分,因此可以访问该类实例的私有成员和受保护成员。免费功能不会。

示例:

class A {
  A(a) : _a(a) {}
private:
  // legal - _a is accessible because get_a is part of A
  static int get_a(const A& a) { return a._a; } 
private:
  int _a;
};

// illegal - _a is a private member of A
static get_a(const A& a) {
  return a._a;
}

编辑以回应OP的编辑。

两种实现都是有效的。

相关问题