我在尝试编写 C++ 库时遇到问题。这是通常的设置,一个 cpp 文件,一个头文件。我希望头文件只公开要使用的部分(例如,我有一个抽象基类,我不想在头文件中)。到目前为止,我只处理一个文件(我认为这应该没有什么区别,因为包含是由预处理器完成的,它不关心任何事情)。
您会注意到“头文件”分布在头文件实现文件之前和之后的两个位置。
#include <stdio.h>
// lib.h
namespace foo {
template <class T> class A;
}
// lib.cpp
namespace foo {
template <class T> class A {
private:
T i;
public:
A(T i) {
this->i = i;
}
T returnT() {
return i;
}
};
};
// lib.h
namespace foo {
template <class T> T A<T>::returnT();
}
// foo.cpp
void main() {
foo::A<int> a = foo::A<int>(42);
printf("a = %d",a.returnT());
}
所以,很自然地,我希望我的头文件只包含
namespace foo {
template <class T> class A;
template <class T> T A<T>::returnT();
}
但我的编译器不喜欢这样(它提示 returnT
不是 foo::A<T>
的成员。我不想将类声明本身放在 header 中的原因是那样的话(就像我理解它),包含我想隐藏的所有私有(private)和类似的东西。
也许只有我一个人觉得下面的头文件看起来“不好”,至少作为“接口(interface)规范”是这样。它公开了 A
的一些内部结构,库的用户不需要知道这一点。
// lib.h
namespace foo {
template <class T> class A {
private:
int i;
public:
A(T);
T returnT();
};
}
// lib.cpp
namespace foo {
template <class T> A<T>::A(T i) {
this->i = i;
}
template <class T> T A<T>::returnT() {
return i;
}
};
这是公认的做法吗?如果可能的话,我想要一个更抽象的头文件。
最佳答案
您不能将模板的定义与其声明分开。它们都必须一起进入头文件。
“为什么?”我推荐阅读 "Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?" .
我可能误解了你的问题。为了解决您的问题,这是无效的:
namespace foo {
template <class T> class A;
template <class T> T A<T>::returnT();
}
无效的原因与无效的原因相同:
namespace foo {
class A;
int A::returnT();
}
成员函数必须在类的定义中声明。
关于C++ 类声明和命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4785678/