Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;-分发不同于开发的头文件_C++_Header - Fatal编程技术网

C++ C++;-分发不同于开发的头文件

C++ C++;-分发不同于开发的头文件,c++,header,C++,Header,我很好奇用C++做这件事: 假设我有一个小的库,分发给我的用户。我为我的客户提供他们需要的二进制文件和相关的头文件。例如,假设开发中使用了以下标题: #include <string> ClassA { public: bool setString(const std::string & str); private: std::string str; }; #包括 甲级 { 公众: 布尔设置字符串(const std::

我很好奇用C++做这件事:

假设我有一个小的库,分发给我的用户。我为我的客户提供他们需要的二进制文件和相关的头文件。例如,假设开发中使用了以下标题:

#include <string>

ClassA 
{
    public:
        bool setString(const std::string & str);

    private:
        std::string str;
};
#包括
甲级
{
公众:
布尔设置字符串(const std::string和str);
私人:
std::字符串str;
};
现在回答我的问题。对于部署,我给我的客户提供一个“简化”的头有什么根本性的错误吗?例如,我是否可以剥离私人部分并简单地给他们以下内容:

#include <string>

ClassA 
{
    public:
        bool setString(const std::string & str);
};
#包括
甲级
{
公众:
布尔设置字符串(const std::string和str);
};
我的直觉告诉我“是的,这是可能的,但有陷阱”,所以我在这里问这个问题。如果这是可能的并且也是安全的,那么它看起来是隐藏私有变量的好方法,因此在某些情况下甚至可以避免向前声明

我知道这些符号仍将存在于二进制文件中,这只是源代码级别的可见性


谢谢

以这种方式修改类声明将导致代码不兼容

编译器需要类声明来计算该类的实例占用的空间以及该空间中哪些成员变量的位置

如果在一个标头中遗漏了成员(甚至是私有成员),则使用此标头编译的代码将采用不同的类布局。它将为类的实例分配更少的空间,并假定成员变量位于不正确的位置。

< P>QT(一组跨平台C++库)使用隐藏头和“D”指针隐藏实现细节的技术。我认为在很长一段时间内维护一个二进制兼容的库是非常巧妙的,但是在必要时可以更改实现


除了sth在回答中所说的之外,我还要补充一点,如果你有理由这样做,那么为什么不简单地将ClassA变成一个“接口”类型的类,它只有纯虚拟函数

然后,您的内部代码将有一个ClassB,它派生自ClassA并实现所有这些纯虚拟函数。您只为ClassA分发标题。显然,用户不能在堆栈上声明ClassA对象,因为ClassA是纯虚拟类,不能直接在堆栈或堆上创建ClassB对象,因为他对ClassB一无所知

公共头文件(将其分发给用户):

专用头文件:

class B : public class A
{
private:
    ...

public:
   B();
   virtual ~B();

   virtual somefunc();
   virtual someotherfunc(int a, int b);
   virtual bool setString(const std::string & str);
};
专用源文件:

classB::B()
{

}

classB::~B()
{

}

classB::somefunc()
{
    ...
}

classB::someotherfunc(int a, int b)
{
    ...
}

classB::setString(const std::string & str)
{
    ...
}

A *CreateObjectB()
{
    return new B();
}

不-那不行-ClassA的大小有一点是错误的。这违反了C++,不会起作用。我对此很担心。谢谢你的回答!另一种隐藏实现细节的常用方法是pimpl习语(“指向实现的指针”);我个人更喜欢这种“接口”方法,但有时pimpl更有意义。
classB::B()
{

}

classB::~B()
{

}

classB::somefunc()
{
    ...
}

classB::someotherfunc(int a, int b)
{
    ...
}

classB::setString(const std::string & str)
{
    ...
}

A *CreateObjectB()
{
    return new B();
}