【问题标题】:Header class file to be used by others其他人使用的头类文件
【发布时间】:2010-12-04 02:08:30
【问题描述】:

我想知道是否有办法只将受保护和公共的东西放在头文件 .h 中,并将所有私有的东西放在编译单元 .cpp 中 我需要这个,因为该库将被其他人使用,我不想复制和编辑所有 .h 文件来删除私有声明和实现。 我试过但得到重复声明错误

另一个问题是关于私有静态的东西 我可以在头文件中声明它们并在 .cpp 单元上实现它们吗? 私有变量和公共 get 方法 我试过但无法在单元上实现该方法,它只适用于标题上的声明和实现

[]s, 乔

【问题讨论】:

    标签: c++ class header private public


    【解决方案1】:

    解决这个问题的正确方法是实现 pimpl 习惯用法:为所有私有数据创建一个类或结构,并将指向此类对象的指针与前向声明一起放在头文件中。现在从头文件中看不到任何私有数据和方法。

    【讨论】:

    【解决方案2】:

    Andreas 有答案,但请注意,这会使您的代码对您自己来说更加迟钝:

     // header file
    
     struct hidden_structure;
    
     class Foo {
         hidden_structure* hidden_data;
     public:
         Foo();
         ~Foo();
    
         void doStuff();
     };
    
     // your cpp file
    
     struct hidden_structure;
         int stuff;
         hidden_structure() : stuff(0) {}
     }
    
     Foo::Foo() : hidden_data(new hidden_structure) {}
     Foo::~Foo() { delete hidden_data; }
    
     void Foo::doStuff() { hidden_data->stuff += 34; } // hey, it does a lot of stuff
    

    如您所见,hidden_​​structure 中的数据越多,它就会变得越复杂。

    【讨论】:

    • 1) 使用智能指针,2) “数据越多,越复杂”是什么意思?复杂性是恒定的(您只需在每个字段引用之前加上 p-> 或任何 pimpl 字段)。
    • 那种代码看起来有点丑。我想我将不得不做这个 PIMPL 或者我应该删除下面的所有内容 private: 在处理给某人之前? :( 我在编写代码和设计代码时浪费了相同的时间。你也会遇到这种情况吗?
    【解决方案3】:

    与 John 的代码相同,但我使用的是指针而不是引用:

    // file.h
    class TheClass_p;
    class TheClass{
      public: 
        TheClass();
        ~TheClass();
      private
        TheClass_p *d;
    
    };
    
    // file.cpp
    class TheClass_p {
      int foo;
      float: bar;
    };
    
    TheClass::TheClass(){
       d = new TheClass_p;
    }
    
    TheClass::~TheClass(){
       delete d;
    }
    

    编辑:添加析构函数以释放内存泄漏

    【讨论】:

    • 你需要在析构函数中释放内存。
    【解决方案4】:

    对此的正确答案是使用 Pimpl(通过 指针,正如 Pavel 指出的那样)。 Matthew Wilson 的Imperfect C++ 中还描述了一种疯狂但可能正确的方法,您可以在其中转发声明一个内部结构并在您的类中包含一个不透明的内存块,然后就地构造内部结构(其定义在实现文件)在实现文件中的主类构造函数中。

    我应该指出,Wilson 在附录中展示了这一点,他在其中承认了一些这样的“反对编程的罪行”,作为对试图过于聪明的程序员的警告。他说,我说,你不应该使用这个。但是,如果您有一些压倒一切的严格性能要求,它可能可能会有一些用处。

    【讨论】:

    • 最好是智能指针,事实上-const std::auto_ptr<T> 非常适合。
    • 此外,您描述的技巧(在对象本身内预分配块,而不是指针)的问题在于它扼杀了 pimpl 提供的另一个优势,这通常比隐藏私有更重要成员 - 它允许您编写版本控制安全的代码,而不受新字段的限制(因为它们都转到私有对象)。对于 perf 实际上非常重要以至于这是一个问题的情况,强制封装可能更不用担心,所以只需“正常”执行即可。
    • Pavel,你是对的(关于版本控制)。正如我希望我强烈传达的那样,我和威尔逊的书都不提倡这种技术。只是(在 C++ 中似乎总是如此),在极少数情况下它可能是一个合理的选择。买家小心! :-)
    【解决方案5】:

    您不能为用户声明完整的类名,而是将类定义放在仅包含公共和私有的 .h 文件中,然后放在公共定义的 .cpp 文件子类中,并且只定义私有?

    像这样:

    .h 文件--

    class useThis;   // users actually use this class
    
    class publics {  //this is the interface they see
    public:
        int foo;
    };
    

    .cpp 文件--

    #include "foo.h"
    
    class useThis: publics {
    
    private:
        void add(int b);
    
    };
    
    void useThis::add( int b )
    {
        foo+= b;
    }
    

    【讨论】:

    • 我认为这行不通。当人们使用标头时,没有什么可以将useThis 绑定到publics
    • 我很确定它确实有效。 publics 中的所有内容也在 useThis 中,因为 useThis 继承自 publics。
    • 这行不通?这似乎是与模板一起使用的好方法
    猜你喜欢
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 2015-08-15
    • 1970-01-01
    • 2021-12-15
    相关资源
    最近更新 更多