【问题标题】:eC (Ecere) how to not worry about private data fields of a classeC(Ecere)如何不担心类的私有数据字段
【发布时间】:2014-08-25 07:06:46
【问题描述】:

在公开库的 C++(或 Java)接口时,必须提供类的“私有”字段,这是不稳定的,因为编译器需要知道类的结构,以便能够例如,计算 sizeof()。

但为什么需要这样做以及如何缓解?因为,对我来说,它似乎违反了封装概念:为什么用户要担心或访问被认为是私有的东西?

一种解决方案是为每个对象定义一个 size() 函数,但这在运行时会很麻烦。

不过,一种语言 (eC/ecere) 声称 [1]:

“库开发人员无需担心最终用户看到的类定义的私有内容,只有声明为公开的内容才会可见”

在 eC 中是如何实现的?如何在 Java 或 C++ 中实现类似的功能?

[1]http://www.ecere.com/technologies.html

【问题讨论】:

    标签: java c++ api encapsulation


    【解决方案1】:

    仅仅因为程序员或编译器可以“看到”私有类型,并不意味着它违反了“封装”。将封装视为“合同”(您不应该使用它,但您仍然可以看到它)。

    ...然而...

    如果你真的想“隐藏”底层表示,你的问题的答案是使用不透明的指针:

    这是一个 C++ 示例:

    http://www.tilander.org/aurora2/Stupid_Cpp_Tricks/index.html

    我购买的早期 C++ 书籍之一是 James Coplien 的“Acid Book” (正如迈耶斯所说)。今天里面的很多东西都有更多的面包 和黄油的东西,虽然你还没有读过它,你应该。之一 詹姆斯(或吉姆,这个名字多么好听)介绍的东西是 Pimpl 惯用语。私有实现是对 奇怪的名字,更合理的是指向实现的指针。在 简单来说,它是一个编译器防火墙,或者一个opaque type 有效地从外部隐藏任何类的实现。

    // in the header
    class Foo
    {
    public:
        Foo();
        ~Foo();
    
    private:
        struct Pimpl; // forward declaration to internal structure
        Pimpl* m; // opaque pointer to actual data
    };
    
    // in the cpp file
    struct Foo::Pimpl
    {
        std::string name;
    };
    
    Foo::Foo()
        : m( new Pimpl)
    {
    }
    
    Foo::~Foo()
    {
        delete m;
    }
    

    【讨论】:

    • 感谢您的回答。信息量很大。我也很好奇 eC 是如何做到这一点的。未能在 eC 中找到说明性示例。 PIMPL 是众所周知的,它还有助于编译(每次添加/删除/修改私有字段声明时,无需重新编译包含标头的所有源文件)但是,它引入了间接级别。
    【解决方案2】:

    您可以通过只公开接口而不是实现来轻松实现封装。在 C++ 中,接口只是一个只有纯虚方法的类:

    class Interface
    {
    public:
        virtual void method() = 0;
    };
    

    如果您的 API 是基于接口的,那么除了封装之外,它还将更加模块化和灵活,耦合更少并且更易于测试。因此非常希望在 API 中使用接口而不是实现类。

    当然,您必须使用工厂、构建器和其他设计模式来构建实现接口的真实实例。

    【讨论】:

    • 谢谢你这么好的回答。我真的很抱歉我不能同时选择“接受”,但你的建议非常非常好,我鼓励赞成这个答案。唯一的缺点是您必须事先考虑这样做。
    【解决方案3】:

    eC 有一个运行时反射模型,它知道所有类的布局,并区分结构(总是就地分配)和类(类总是在堆上分配,由知道类布局的运行时机制) .

    这背后的想法是,可能很多和/或连续的小对象(例如点)更适合结构,而需要内存管理的更复杂的对象更适合类。这也可以允许交换具有相同界面但布局完全不同的库。

    对 C++ 'pimpl' 的需求只是我无法忍受 C++(另一个是头文件)让我设计 eC 的原因之一,因为我对尝试为 Ecere 构建 C++ 类库感到不满。

    我已经看到 C++ 代码扩展到 4 个不同的文件,分别用于 API、API 标头、实现、实现标头,每个文件中有很多行,而不是简单地在 eC 中:

    public class MyClass
    {
       public int myFunction() {  }
       private int myPrivateMember;  
    }
    

    顺便说一句,eC 有一个新网站 :) http://ec-lang.org(仍有待改进)。 而且我总是很乐意回答问题并在论坛和 IRC 上提供帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 2021-06-24
      • 2014-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多