C++ 类声明和命名空间

标签 c++ templates class namespaces header-files

我在尝试编写 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/

相关文章:

c++ - 使用 std::tuple 构建基于 vector 的数据集请引用 variadic-templates

java - 来自多个来源的 Spring MVC 复杂模型填充

javascript - Meteor js 类和内容

c++ - 打印链表 - C++

c++ - 对具有许多模板参数的类进行操作

C++ 静态类成员 - 语法错误

java - 为什么类在 Java 中声明为静态的?

c++ - 使用 vector A 的位置和方向创建 vector B

c++ - 无法创建 OgreBullet Trimesh

C++ 获取 linux 发行版名称\版本