有一个文件,包含两个独立的类和一个函数:
int foo(int x) {return x+x;}
class A {
public:
int bar(){return foo(0);}
};
class B {
public:
int bar(){return foo(1);}
};
他们都需要使用功能
其仅使用其自变量(不使用来自A或B的任何数据(。我可以将此函数声明为全局函数。但我想为其他文件隐藏这个函数(所以这在其他文件中是不可见的,不可访问的(。所以我可以将这个函数声明为每个类A和B的成员函数。但这将是代码重复。
最好的做法是什么?
您可以从任何标头中省略foo
的任何声明,并将其标记为static
或在匿名命名空间中定义它。
AB.h-
class A { int bar(); };
class B { int baz(); };
AB.cpp
static int foo(int x) { return x+x; }
/* or
namespace {
int foo(int x) { return x+x; }
}
*/
int A::bar() { return foo(1); }
int B::baz() { return foo(2); }
您可以简单地将函数放在另一个只存在于该文件中的类中:
class C
{
public:
static void foo(int) {}
};
class A
{
void test1()
{
C::foo(0);
}
};
class B
{
void test2()
{
C::foo(0);
}
};
A&B现在可以访问这个函数,并且它没有被全局声明。
您也可以将函数放在自己的命名空间中:
namespace ABFunctions
{
void foo(int) {}
}
从逻辑上讲,这是保持它分离的另一种方式。
如果你需要保护访问,你可以这样做:
class C
{
friend class A;
friend class B;
private:
static void foo(int) {}
};
class A : C
{
void test1()
{
C::foo(0);
}
};
class B : C
{
void test2()
{
C::foo(0);
}
};
现在,只有A类&B将有权访问foo(int)
。
您可以创建一个基类并从中派生。您不必重复代码。
class Base {
virtual ~Base = 0;
protected:
int foo(int x) {return x+x;}
};
class A : public Base {...}
class B : public Base {...}
不能实例化Base
的对象。
如果它不使用来自A或B的任何数据,那么它可能不应该在A或B中实现。听起来f好像是某种辅助函数。也许创建一个类Utilities
并使其成为实用程序类的公共静态函数会更好。
在c++中,在命名空间级别没有隐藏函数的,尽管您可以创建一个只包含私有静态函数的实用程序类,并使用friend
关键字显式指定哪些类可以访问:
class C {
friend class A;
friend class B;
static void foo(int);
};
int foo(int x) {return x+x;}
class A {
public:
int bar(){return C::foo(0);}
};
class B {
public:
int bar(){return C::foo(1);}
};
虽然这不是一个很好的设计模式,但由于friend
引入了更多的维护工作,因此除了A
或B
之外的其他类也需要访问foo
。
一个可能更好的模式是使用我在问答中勾画出的界面;A在这里:
- 如何正确删除/重构«friend»依赖声明
尽管接口的引入受到virtual
多态性的开销的影响。也许这可以通过CRTP引入静态多态性来解决。
关于维护和重用实现细节的更广泛视图,为什么要像函数foo()
严格要求的那样隐藏这些细节。为什么您需要隐藏这个实现细节?