为C+;创建最小版本准备头文件+;班 我制作了一个C++类,我把它放在自己的静态库中。

为C+;创建最小版本准备头文件+;班 我制作了一个C++类,我把它放在自己的静态库中。,c++,osx-lion,static-libraries,header-files,C++,Osx Lion,Static Libraries,Header Files,我还决定创建一个最小的头文件,允许其他人查看类的public:部分。所以我基本上取了原始的头文件(它相当长,包含类的private:和public:部分,等等),去掉了public:部分以外的所有内容(很短,只有构造函数/析构函数和一个公共函数) 为了进行测试,我创建了一个虚拟项目,该项目将使用该库。问题是,每当我在该项目中使用最小头文件时,它都会崩溃,出现如下消息: test(44349) malloc: *** error for object 0x7fdab2c242e8: incorre

我还决定创建一个最小的头文件,允许其他人查看类的
public:
部分。所以我基本上取了原始的头文件(它相当长,包含类的
private:
public:
部分,等等),去掉了
public:
部分以外的所有内容(很短,只有构造函数/析构函数和一个公共函数)

为了进行测试,我创建了一个虚拟项目,该项目将使用该库。问题是,每当我在该项目中使用最小头文件时,它都会崩溃,出现如下消息:

test(44349) malloc: *** error for object 0x7fdab2c242e8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
但是,每当我包含原始头文件时,它都可以正常工作


有什么问题吗?它可以使用最小头文件和原始头文件进行良好编译(即使使用
-Wall
,也不会出现警告)。

不能从接口中删除类的私有/受保护部分:使用接口的编译器必须知道(私有/受保护)成员变量和虚拟函数,否则,它将对类实例和虚拟表有错误的理解。

不能从接口中删除类的私有/受保护部分:使用接口的编译器必须知道(私有/受保护)成员变量和虚拟函数,否则它会对类实例和虚拟表有错误的理解。

这不起作用,并且违反了一个定义规则:每个类必须有一个精确的定义,每个翻译单元必须看到完全相同的定义,否则您的程序格式不正确,更糟糕的是,不需要诊断

使用PIMPL习惯用法可能会更好,通过该习惯用法,您可以将类分为两部分,并且不需要公开实现组件:

// Ship this:

class FooImpl;

class Foo
{
    std::unique_ptr<FooImpl> impl;
public:
    Foo();
    void do_magic();
};

// Don't ship this:

class FooImpl { void magic(); };
void FooImpl::magic() { /* secret code */ }

Foo::Foo() : impl(new FooImpl) { }
void Foo::do_magic() { impl->magic(); }
//发送此文件:
类FooImpl;
福班
{
std::唯一的\u ptr impl;
公众:
Foo();
虚无的魔力;
};
//不要发送此文件:
类FooImpl{void magic();};
void FooImpl::magic(){/*密码*/}
Foo::Foo():impl(新的FooImpl){}
void Foo::do_magic(){impl->magic();}

有关PIMPL类的通用框架,请参见Herb Sutter's。

这不起作用,并且违反了一个定义规则:每个类必须有一个精确的定义,每个翻译单元必须看到完全相同的定义,否则您的程序格式不正确,更糟糕的是,不需要诊断

使用PIMPL习惯用法可能会更好,通过该习惯用法,您可以将类分为两部分,并且不需要公开实现组件:

// Ship this:

class FooImpl;

class Foo
{
    std::unique_ptr<FooImpl> impl;
public:
    Foo();
    void do_magic();
};

// Don't ship this:

class FooImpl { void magic(); };
void FooImpl::magic() { /* secret code */ }

Foo::Foo() : impl(new FooImpl) { }
void Foo::do_magic() { impl->magic(); }
//发送此文件:
类FooImpl;
福班
{
std::唯一的\u ptr impl;
公众:
Foo();
虚无的魔力;
};
//不要发送此文件:
类FooImpl{void magic();};
void FooImpl::magic(){/*密码*/}
Foo::Foo():impl(新的FooImpl){}
void Foo::do_magic(){impl->magic();}

有关PIMPL类的通用框架,请参阅Herb Sutter's。

这似乎很有希望,谢谢。所以没有其他(更简单的)方法了?我必须使用两个类?所有C++库都这样做吗?@ HouBySuff:我认为大多数C++库不必麻烦隐藏事物。最终,允许客户机查看类的非公共部分并没有概念上的惩罚。无论如何,你绝对不能违反ODR。我明白了。。。我并不是真的想隐藏东西,但我的类的一些
private
函数有自定义类型,用于需要其他头文件等的参数,因此在头文件的发布版本中去掉这些类型会简单得多…@houbysoft:PIMPL肯定有助于解耦编译依赖关系,许多大型项目都将它作为一个基本的规程来保持编译时间的可管理性。这似乎很有希望,谢谢。所以没有其他(更简单的)方法了?我必须使用两个类?所有C++库都这样做吗?@ HouBySuff:我认为大多数C++库不必麻烦隐藏事物。最终,允许客户机查看类的非公共部分并没有概念上的惩罚。无论如何,你绝对不能违反ODR。我明白了。。。我并不是真的想隐藏东西,但我的类的一些
private
函数有自定义类型,用于需要其他头文件等的参数,因此在头文件的发布版本中去掉这些类型会简单得多…@houbysoft:PIMPL肯定有助于解耦编译依赖关系,许多大型项目将它作为一个基本的规程来保持编译时间的可管理性。