C++ 在类外部定义的类typedef

C++ 在类外部定义的类typedef,c++,c++11,C++,C++11,我正在编写一个类C,它有一个内部类T,我希望T的详细信息隐藏为C的内部实现。C中的方法都使用指向T的指针。这当然是可能的,因为: // In header class C { public: class T; T* f(); void g(T*); }; // In .cpp class C::T { /* details here */ }; 现在我的问题是,如何在.cpp文件中将C::T定义为另一个的类型别名。以下内容根本不编译,但它说明了我要做的事情: // Outside

我正在编写一个类
C
,它有一个内部类
T
,我希望
T
的详细信息隐藏为
C
的内部实现。
C
中的方法都使用指向
T
的指针。这当然是可能的,因为:

// In header
class C {
public:
  class T;
  T* f();
  void g(T*);
};

// In .cpp
class C::T { /* details here */ };
现在我的问题是,如何在
.cpp
文件中将
C::T
定义为另一个的类型别名。以下内容根本不编译,但它说明了我要做的事情:

// Outside the class C
using C::T = std::string;

在保持目标的同时,是否有任何解决方法,即隐藏
C::T
的细节?

您不能,因为转发声明
类TC
中的code>声明了一个真实名称为
C::T
的类类型,因此与真实名称为
std::basic_string
的类型不同

你可以考虑以下内容:

// C.h
#include "internal/T.h"
namespace foo {
class C {
public:
  using T = internal::T;
  // ...
};
}

// internal/T.h
namespace foo { namespace internal {
using T = std::string;
}}

最接近这一点的方法是让t从字符串派生:

class C::T : public std::string { ... };

T
永远不能真正隐藏或重新定义为不同.cpp文件中的类型别名

下面的方法应该适合您的需要

class C
{
   public:

      // Use a base class for just the pointers.
      struct TBase
      {
         virtual ~TBase() {}
      };

      TBase* f();
      void g(TBase*);

      // Allow client code to define a concrete type using a template parameter.
      template <typename Data> struct T : TBase
      {
         Data data;
      };
};
C类
{
公众:
//只对指针使用基类。
结构数据库
{
虚拟~TBase(){}
};
TBase*f();
无效g(待定*);
//允许客户端代码使用模板参数定义具体类型。
模板结构T:TBase
{
数据;
};
};
然后,在.cpp文件中,使用:

using Type = C::T<std::string>;

Type* obj = new Type;
obj->data = "Some string";

C c;
c.g(obj);
TBase* ptr = c.f();
使用Type=C::T;
类型*obj=新类型;
obj->data=“一些字符串”;
C C;
c、 g(obj);
TBase*ptr=c.f();

正如其他人指出的那样,这是不可能做到的。我的建议是:

// .h
class C {
public:
  struct T;
  T* f();
  void g(T*);
};

// .cpp
struct C::T
{
  IMPL_TYPE data;
  //If one is carefull with lifetimes this can almost in any context act as IMPL_TYPE.
  //And if necessary, the data member can be accessed.
  operator IMPL_TYPE&(){return data};
}

你的意思是宁愿使用模板吗?你不能。T不是别名,它是一种类型。@NathanOliver,我明白如果我在
C
的声明中定义
class T
,这是不可能的。我正在寻找的解决方案不必保持行
classt
C
的声明中。它可以是
typename T
(当然我知道这也不起作用)。也许你想让类T有一个使用PIMPL的私有实现@昆比。编译器肯定可以编译用户代码,而不知道T是什么,因为编译器肯定知道指针有多大。这肯定有帮助,但仍然不能完全隐藏实现细节。理想情况下,类
C
的用户不需要看到
t
@KanLi的声明,他们不需要。如果你的代码有很好的文档,那么用户就不需要阅读内部标题。但是,必须注意的是,
internal::T
是使用另一个间接级别定义的,但它并不是真正隐藏的。