C++ 处理不完整类型

C++ 处理不完整类型,c++,incomplete-type,C++,Incomplete Type,我有两个类:一个类的类型不完整,第二个类需要使用不完整的类型。是否有任何方法可以引用“外部类型”,其方式与引用外部对象的方式类似 编辑:有关我的类结构的详细信息 不幸的是,我也不能使用指针。我的代码如下所示: class CompleteA { private: friend CompleteB; struct IncompleteA; boost::shared_ptr<IncompleteA> data_; }; class CompleteB {

我有两个类:一个类的类型不完整,第二个类需要使用不完整的类型。是否有任何方法可以引用“外部类型”,其方式与引用外部对象的方式类似


编辑:有关我的类结构的详细信息

不幸的是,我也不能使用指针。我的代码如下所示:

class CompleteA {
  private:
    friend CompleteB;
    struct IncompleteA;
    boost::shared_ptr<IncompleteA> data_;
};

class CompleteB {
   public:
     void SomeFct(CompleteA& a) {
        // I need to access a member of the incomplete type
        a.data_->someMember;
     }
};
class complete{
私人:
完全的朋友;
结构不完全;
boost::共享的ptr数据;
};
类CompleteB{
公众:
无效部分(完整的a和a){
//我需要访问不完整类型的成员
a、 数据成员;
}
};
我可以有一个单独的头文件和源文件对,但在我的情况下,这会有点过分。不完整的类型只是一个有一个成员的结构;我使用它来隐藏实现。(但是,如果没有其他选择,我将使用单独的标题…)


关于我对朋友的使用,请忽略这一点,集中精力在我所请求的帮助上。我考虑过是否应该在这里使用friend,我得出结论,使用getter(而不是friend)将暴露实现。

我无法正确理解您的问题

但据我所知,我只能说不完整的类型只能在代码中用作
指针

struct A; //incomplete type, since it has not been defined yet!

A *pA; //okay - pointer to an incomplete type is allowed!
A  a;  //error - cannot declare an automatic variable of incomplete type!

我希望这些信息能帮助您找到问题的实际解决方案

使用正向声明

在你的另一节课上。h:

class IncompleteClass;

class YourOtherClass
{
    IncompleteClass* member;
};
在yourotherclass.cpp中,您实际上需要包含uncompleteClass.h才能使用指针

编辑:响应您的详细信息:

如果要隐藏实现,请为此创建一个单独的(friend)类并引用该类:

class CompleteAImpl
{
    friend CompleteA;
    // data, members, etc. that you intend to hide
};

class CompleteA
{
    CompleteAImpl* priv; // or shared_ptr if you want
};

我想你想做这样的事。实现中的问题是,为了引用结构/类中的成员,编译器需要知道该成员和前面成员的大小。您可以将
(a.data+sizeof(所有前面的成员))
转换为
someMember
的类型,并取消对该类型的引用;但是这是一个丑陋且不安全的解决方案。

如果您只需要访问
某个成员,那么有一个非常简单的解决方案:提供一个带有越界定义的私有getter

class A {
private:
  friend B;
  int getSomeMember() const; // defined in .cpp

  struct IncompleteA;
  boost::shared_ptr<IncompleteA> data_;
};

class B {
public:
  void SomeFct(A& a) {
    a.getSomeMember();
  }
};
A类{
私人:
朋友B;
int getSomeMember()const;//在.cpp中定义
结构不完全;
boost::共享的ptr数据;
};
B类{
公众:
无效部分(A&A){
a、 getSomeMember();
}
};

这是一个非常广泛的问题。你可能想发布一个你想做的事情的例子,然后有人可能会为你提供一个解决方案。既然CompleteB是你的朋友,我不明白你为什么不在CompleteTea中使用私有getter(在其他地方实现),就像@Matthieu M.建议的那样。这里绝对没有问题,不完整类型的pimpl习语很常见,这是连接到pimpl类实现的方式。它也可以用作
boost::shared_指针
,通过一些增强魔法:不需要
A
的析构函数,因为它将在共享指针的构造时作为删除程序传递。聪明。@Alexandre C:我第一次注意到,用于删除程序的类型擦除非常简单,但也令人印象深刻。这是您想要在工具箱中使用的东西:)因为我特别说过,在这种情况下,getter不好,因为expose实现。@Paul:私有getter不会再公开任何内容。而且您正在使用friend类,所以您已经公开了实现。@Paul:如果您需要使用
someMember
,那么您需要知道它的类型,无论是通过直接访问还是通过getter获取。另一方面,getter隐藏了
IncompleteA
B
的细节,因此增加了封装性。还要注意,它是私有的,因此只暴露于
A
本身和
B
(因为它是朋友)。@Matthieu M:不完整类型的目的是消除头文件中使用的任何第三方库的所有痕迹。拥有一个getter(甚至是private)首先会破坏不完整类型的目的。我宁愿用一个新类
AImplementation
,或者别的什么东西来创建一个新的标题。@Paul:我们不是说这里给出的解决方案在您的情况下是最好的,但我确实认为它是您给出的草图中最好的。请注意,私有getter返回的值需要是
IncompleteA
的内部值,它更简单,但完全可以是代理或
a
B
之间共享的任何内容。这是使用方法而不是直接访问属性的一个优点。