代码之家  ›  专栏  ›  技术社区  ›  user283145

转发声明命名空间内的全局类型

  •  2
  • user283145  · 技术社区  · 15 年前

    我想使用第三方库而不使用其头文件。我的代码驻留在它自己的名称空间中,因此我不能使用常规的前向声明,因为我不想污染全局名称空间。目前我有这样的东西:

    3rd-party-library.h----
    
    typedef struct {...} LibData;
    void lib_func (LibData *);
    
    my-source.h-----
    
    namespace foo {
    
        /*forward declaration of LibData*/
    
        class Abcd {
            public:
                void ghj();
            private:
                Libdata *data_;
            };
        }//namespace foo
    
    my-source.cpp-----
    #include "my-source.h"
    #include <3rd-party-library.h>
    
    namespace foo {
        typedef ::LibData LibData;
        void Abcd::ghj() {
            //do smth with data_
            }
        }//namespace foo
    

    是否可以转发声明一个全局类型,使其驻留在一个命名空间中?普通简单typedef不起作用。

    3 回复  |  直到 15 年前
        1
  •  7
  •   Jan    15 年前

    为了使前向声明有效,需要在适当的命名空间中前向声明一个对象。由于原始对象位于全局命名空间中,因此需要在全局命名空间中转发声明它。

    如果你不喜欢,你可以用你自己的结构来包装它:

    namespace foo {
    struct libDataWrapper; }
    

    在你自己的cpp中定义这个结构。或者,如果你能做到这一点,你可以总是诉诸于虚无等等。

        2
  •  2
  •   YeenFei    15 年前

    因为您使用的是指针,所以我“向前”在您自己的命名空间中声明一个虚拟对象,然后使用reinterpret_cast将实际对象绑定到现有指针。

    你的来源

    namespace foo {
    
    //forward declare
    class externalObj;
    
    class yourObj
    {
    public:
      yourObj();
      ~yourObj();
      void yourFunction();
    
    private:
     externalObj* pExt;
    };
    
    }
    

    您的-implementation.cpp

    #include "your-source.h"
    #include "externalObj-header.h"
    
    namespace foo {
    
    yourObj::yourObj() :
    pExt ( reinterpret_cast<externalObj*>(new ::externalObj()) )
    {
    }
    
    yourObj::~yourObj()
    {
    }
    
    void yourObj::yourFunction()
    {
       reinterpret_cast<::externalObj*>(pExt)->externalFunction();
    }
    
    }
    
        3
  •  1
  •   Frederik Slijkerman    15 年前

    不能简单地将第三方库的include包装在自己的名称空间中吗?

    namespace ThirdParty {
    #include "thirdparty.h"
    }
    
    namespace foo {
    
      ... your code
    
      ThirdParty::LibData *d;
    
    }