我已经设计和开发了SHARED库,并希望分发它,但是我不想公开私有方法和私有属性。
这是我尝试的没有成功的事情:
完整标头,用于构建库mylib.so:
namespace MYNAMESPACE{
enum class MyReturnCode {
Success = 1,
MyRetCode01,
MyRetCode02
};
class MyException {
public:
MyException(
MYNAMESPACE::MyReturnCode _code,
std::string _message);
MYNAMESPACE::MyReturnCode code;
std::string message;
};
class MyClass {
public:
MyClass();
~MyClass();
void initialize();
std::string function01();
std::string function02();
int attribute01;
float attribute02;
private:
std::string function03();
int attribute03;
float attribute04;
};
}
我设计用于与他人共享mylib.so时使用的标头与此相似,但没有私有部分。
当我调用函数initialize
时,属性attribute03
和attribute04
的设置正确,并且可以一直使用。
所有此情况下的实际问题
我不知道为什么,但是在某个时候,attribute03
和attribute04
只是有些垃圾,我有一个SIGABRT
结束了执行。
已编辑(第二次)
经过一番评论,我进入了以下PIMPL解决方案,现在它可以正常工作。
标头my_class_api.hpp,用于与mylib.so一起分发
#include <memory>
namespace MY_API {
class MyClassAPI {
public:
virtual ~MyClassAPI() {};
virtual void initialize() = 0;
virtual std::string function01() = 0;
virtual std::string function02() = 0;
static std::shared_ptr<MyClassAPI> get_my_api();
};
}
新的完整标头my_class.hpp,用于构建库mylib.so:
#include "my_class_api.hpp"
namespace MYNAMESPACE{
class MyClass : public MY_API::MyClassAPI {
public:
MyClass();
~MyClass() override;
void initialize() override;
std::string function01() override;
std::string function02() override;
private:
std::string function03();
int attribute03;
float attribute04;
};
}
实施文件my_class.cpp
#include "my_class.hpp"
namespace MY_API {
std::shared_ptr<MyClassAPI> MyClassAPI::get_my_api() {
return std::make_shared<MYNAMESPACE::MyClass>();
}
}
namespace MYNAMESPACE {
MyClass::MyClass() { }
MyClass::~MyClass() { }
void MyClass::initialize() { }
std::string MyClass::function01() { }
std::string MyClass::function02() { }
}
感谢所有帮助我的人!我希望这个例子也能帮助其他人。
答案 0 :(得分:0)
如上所述,PIMPL是最好的解决方案。例如,Qt在其所有类上使用PIMPL来确保二进制兼容性。也就是说,当安装了较新版本的DLL时,它与所有旧的二进制文件兼容,因为公共接口不会更改。
答案 1 :(得分:0)
我设计用于与他人共享mylib.so时使用的标头与此相似,但没有私有部分。
用于构建.so共享库的标头应与公开给客户端的标头相同。一个不能拥有私人成员,另一个不能拥有私人成员。客户端不会将私有成员视为类的一部分,但是在执行功能时,它将尝试使用不属于该实例的内存。
如上所述,PIMPL是一种常用的解决方案。在您班级的私有部分,您可以拥有MyClassData * mData;宣言。在您的.cpp文件中,您可以定义结构MyClassData并初始化其成员。在构造函数中,将内存分配给mData,然后在析构函数中删除该内存。