3

我是构建用 C++ 编写的可分发库的新手,我有点迷路了。我创建了一个 .cpp 文件,其中包含我希望库为用户提供的所有功能的包装器,并且我编写了 2 个 .h 文件,一个是公共的,一个是私有的。下面是我的头文件的一个虚拟示例:

公共.h:

class myclass
{
public:
    public_function();
private:
}

私人.h:

class myclass
{
public:
    public_function();
private:
    anotherClass instanceofClass;
}

请注意,public_function()代码中的实现使用了“instanceofClass”。我已经能够毫无问题地使用私有类编译代码,并使用公共头文件和编译库编译库并将其与外部程序链接。但是,在执行该代码时,我遇到了分段错误,我怀疑这与缺少“instanceofClass”的正确初始化有关。

我在做正确的事吗?我是否被迫在实现中实例化“instanceofClass”public_function()以使其正确初始化,或者我应该做些什么?

非常感谢。

4

4 回答 4

6

您不能以两种不同的方式声明同一个类“myclass”。必须有一个单一的类定义。如果你想隐藏实现的 API,你想使用“Pimpl”成语。所以你的公共类有一个指向私有类的指针。例如:

公共.h

class myclass_private;
class myclass {
    private:
        myclass_private* pimpl; 
    public:
        myclass();
        void public_function();
};

公共.cpp

myclass::myclass() {
    pimpl = new myclass_private;
}

void myclass::public_function() {
     pimpl->private_function();
}

私人的.h

class myclass_private {
    public:
        void private_function(); 
};
于 2012-11-18T00:00:42.230 回答
1

您的类缺少适当的构造函数,这意味着编译器将根据类定义的内容提供一个默认构造函数。如果该定义在所有代码中不一致,则不会在所有地方都以相同的方式初始化,并且可能会丢失一些数据。

如果您想隐藏 的实现细节instanceofClass,只需在标头中进行前向声明(您提供的私有标头是正确的,您可以将其用作公共标头),并在代码中的某处提供实现。

于 2012-11-18T00:10:25.480 回答
1

public.h中myclass定义的没有成员,因此大小为 1 字节。myclassprivate.h 中定义的封装了,anotherClass因此无论大小如何anotherClass。这种不一致是您问题的根源。

你应该做的是只有一个头文件,并使用一个指针(不需要类定义)来隐藏anotherClass. 我将重复 Joachim与 pimpl 成语的链接以进行详细说明。

于 2012-11-18T00:00:00.490 回答
1

类的定义在不同的翻译单元之间不能改变。这是单一定义规则的方面之一。您可能希望将公开可见的类定义为具有指向私有实现的指针:Pimpl Idiom:

class Public {
public:
    ...
private:
     struct Impl;
     Impl* impl_;
};

struct Impl只会在实现文件中定义。

于 2012-11-18T00:03:50.853 回答