我是构建用C ++编写的可分发库的新手,我有点迷失了。 我创建了一个.cpp文件,其中包含我希望库为用户提供的所有函数的包装器,我编写了2个.h文件,一个是公共文件,一个是私有文件。下面是我的头文件的虚拟示例:
class myclass
{
public:
public_function();
private:
}
class myclass
{
public:
public_function();
private:
anotherClass instanceofClass;
}
请注意public_function()
的实现使用" instanceofClass"在代码中。
我已经能够使用私有类编译没有问题的代码,并使用公共头和编译库编译和链接库与外部程序。但是,在执行该代码时,我遇到的分段错误,我怀疑与缺少正确初始化" instanceofClass"。
我做对了吗?我是否被迫实例化" instanceofClass"在public_function()
的实现中,是为了正确初始化,还是我应该做的其他事情呢?
非常感谢。
答案 0 :(得分:6)
你不能宣布同一个班级' myclass'以两种不同的方式。必须有一个类定义。如果您想隐藏实施的API,您想要使用' Pimpl'成语。所以你的公共类有一个指向私有类的指针。例如:
public.h
class myclass_private;
class myclass {
private:
myclass_private* pimpl;
public:
myclass();
void public_function();
};
public.cpp
myclass::myclass() {
pimpl = new myclass_private;
}
void myclass::public_function() {
pimpl->private_function();
}
private.h
class myclass_private {
public:
void private_function();
};
答案 1 :(得分:1)
public.h中定义的myclass
没有成员,因此大小为1个字节。 private.h中定义的myclass
封装了anotherClass
,因此大小为anotherClass
。这种不一致是问题的根源。
您应该做的只有一个标头,并使用指针(不需要类定义)来隐藏anotherClass
的实现。我将重复约阿希姆与the pimpl idiom的链接以进行详细说明。
答案 2 :(得分:1)
不同翻译单位之间的类别定义不得更改。这是One Definition Rule的一个方面。你可能想要什么来定义公开可见的类以获得指向私有实现的指针:Pimpl Idiom:
class Public {
public:
...
private:
struct Impl;
Impl* impl_;
};
struct Impl
只能在实现文件中定义。
答案 3 :(得分:1)
您的类缺少适当的构造函数,这意味着编译器将根据类定义的内容提供默认值。如果该定义在所有代码中不一致,则不会在任何地方以相同的方式初始化,并且可能缺少某些数据。
如果你想隐藏instanceofClass
的实现细节,只需在标题中进行前向声明(你提供的私有标题是正确的,你可以将它作为公共标题使用),并提供一个在代码中的某处实现。