C++ 数据隐藏在C++;

C++ 数据隐藏在C++;,c++,c,incomplete-type,data-hiding,C++,C,Incomplete Type,Data Hiding,我有一些C语言的代码,以这种方式使用不完整的结构(简化示例): 什么的 class Something { public: Something(); private: struct HiddenData; HiddenData* m_pHidden; }; somecode.c 我在想,我基本上在这里做C++,为什么不尝试用C++编写呢? 问题是(我是C++新手),我如何在C++中实现同样的任务?如果我试图添加声明一个不完整类的成员函数,我会得到 error: incomplete t

我有一些C语言的代码,以这种方式使用不完整的结构(简化示例):

什么的

class Something {
public:
 Something();

private:
 struct HiddenData;
 HiddenData* m_pHidden;
};
somecode.c

我在想,我基本上在这里做C++,为什么不尝试用C++编写呢? 问题是(我是C++新手),我如何在C++中实现同样的任务?如果我试图添加声明一个不完整类的成员函数,我会得到

error: incomplete type 'something' named in nested name specifier
从叮当声。通过在头文件中编写完整的类,这将失去数据隐藏的全部意义,更改类中的私有变量将迫使包括“something.h”在内的每个文件重新编译,我认为这里不需要这样做。我不需要使用“something.h”的文件来知道这个结构/类的大小,我通常只需要一个指针就可以了。我怀疑它应该是这样的:

 class Something;

 Something::Something();
 Something::~Something();
 int Something::work_a(int x);

这样我就可以编写与C语言相同的东西,只是更短,甚至更干净。有任何C++程序员希望启发这个致命的C编码器吗?

< P>一个实现这一点的方法是通过PIPML设计模式,在这个模式中,你有一个指针指向一些只有你的实现知道的私有结构/类。您的私有函数使用指针,从理论上讲,它主要是内联的。

请看这篇文章:。它会让你指向你所看到的方向。请注意,继承是用来实现目标的。还可以理解,在C++中,Struts是一个具有所有公共访问成员的类(包括函数、构造函数和析构函数)。至少,接口必须声明为类,然后在cpp文件(而不是另一个头文件)中的现已隐藏的类实现中从该类公开继承


在Pimpl设计模式上,查看以下堆栈溢出文章:。它也应该有帮助。

当您使用新语句分配内存时,编译器必须知道要分配多少数据空间。在使用new创建Something实例之前,编译器已经查看了Something的数据大小

在某物中使用类似的东西

class Something {
public:
 Something();

private:
 struct HiddenData;
 HiddenData* m_pHidden;
};
在something.cpp中使用类似的内容

struct Something::HiddenData {
int a;
int b;
})


谢谢,在实现过程中始终将类强制转换为另一个类的想法似乎是个好主意,我相信编译器很容易对其进行优化。唯一的事情是,我在寻找C++的解决方案,它比我在C.写的更干净,更不那么陈腐,所以我会把问题保持开放。(顺便说一句,pimpl的事情看起来很可怕,我已经把东西藏在一个指针后面了,我不会再把另一个指针放在那个指针后面。)@BuellaGábor你可以随时利用
dynamic_cast
操作符。这完全取决于目标是什么。等等,什么?为什么新的声明需要知道大小?我所要求的只是一个指针,实现给了我这个指针,分配的东西将在另一个编译单元中(至少这是我在C中所做的)。我会理解它,如果它只是堆栈上的一个变量,但它只是堆栈上的一个指针。我遗漏了什么?好的,我快速浏览了维基百科,它说“new是一种语言构造,它动态地从空闲存储分配内存,并使用构造函数初始化内存。”所以new首先分配空间本身,然后调用构造函数。因此,不是构造函数分配了所有数据,它只是应该初始化已经分配的数据。您显示的错误:错误:嵌套名称说明符中命名的不完整类型“something”与编译器没有足够的信息来分配什么来调用构造函数和构建对象有关。我展示的代码是一种很好的数据隐藏方法about@BuellaG在pimpl中,您必须保留一个指针,而且只能保留一个指针。GaryAsh你可能想编辑你的答案。好吧,在我看来,它没有隐藏数据,我必须在标题中键入它。在我的原始版本中,我只有一个指向任意数据的指针,我不希望隐藏的数据比这个少。在我看来,有一个指向类的指针包含另一个指向数据的指针会让情况变得更糟,而不是更好。它还有一个间接性,而且看起来更像黑客。正如我现在看到的,不能使用new关键字,仍然隐藏它指向的数据,因为它需要知道数据的大小。
struct Something::HiddenData {
int a;
int b;
Something::Something() : m_pHidden(new HiddenData()) {
 m_pHidden->a = 1;
}