假设我希望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中访问。
我并不是说如何防范恶意代码等等。
答案 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的编辑。
两种实现都是有效的。