美文网首页bentley开发C++ 2a
EditElementHandle用法和思考

EditElementHandle用法和思考

作者: 左图右码 | 来源:发表于2022-03-13 12:07 被阅读0次

其实我不愿意写有关microstation的代码,有点专,有点窄,API有点糙,甚至很多与经典范式和准则都是背道而驰的,永远看上去像个半成品,仅仅用它当成解释目标议题的样例来看吧。

借助EditElementHandle/ElementHandle,程序员可以摆脱了危险的指针(MSElmdscrP,C的遗产)操作,在多个退出条件不用都进行手工的free,这是得益于大名鼎鼎的RAII,这是C++进行资源管理的标准范式。
但是还有那么一点点不适,你可能还不能那些随心所欲:

//EditElementHandle节选
struct  EditElementHandle : public ElementHandle
{
private:
    EditElementHandleR operator= (EditElementHandleCR from); // illegal!!
    explicit EditElementHandle (ElementHandleCR from);        // illegal!!
    explicit EditElementHandle (EditElementHandleCR from);    // illegal!!
public:
    EditElementHandle() {}
    EditElementHandle (MSElementDescrP descr, bool owned, bool isUnmodified, DgnModelRefP modelRef=NULL)  {}
    EditElementHandle (ElementRefP elRef, DgnModelRefP modelRef=NULL) : ElementHandle (elRef, modelRef) {}
    EditElementHandle (MSElementCP el, DgnModelRefP modelRef) : ElementHandle (el, modelRef){}
    EditElementHandle (ElementId id, DgnModelRefP modelRef) : ElementHandle (id, modelRef) {}
    EditElementHandle (ElementHandleCR from, bool duplicateDescr);
    void Duplicate (ElementHandleCR);
   ...

有几个私有的未实现的复制构造和赋值构造函数。说明这个struct不能作为左值存在,下面的代码是不能通过编译的:

EditElementHandle EditElementHandleFromId(ElementID id)
{
    //do something...
    return EditElementHandle(id,ACTIVEMODEL);
}

error C2440: “return”: 无法从“Bentley::DgnPlatform::EditElementHandle”转换为“Bentley::DgnPlatform::EditElementHandle”
note: struct“Bentley::DgnPlatform::EditElementHandle”的构造函数声明为“explicit”

不能如标准类型,比如int,double,std::string...那么丝滑,有点反直觉。
有几种变通的方法,比如传参后,调用placement new,开销没有增加:

void EditElementHandleFromId(EditElementHandle& eeh, ElementId id)
{
    ::new(&eeh)EditElementHandle(id, ACTIVEMODEL);
}

我常用的最优雅的方法就是借助智能指针了:

auto EditElementHandleFromId(ElementId id)
{
    return std::make_shared<EditElementHandle>(id, ACTIVEMODEL);
}

因为它可以以左值的方式出现。
调用不同的构造方式构建,然后直接返回,中间的临时变量都不需要了:

std::shared_ptr<EditElementHandle> QCPGraphDataHelper::createSectionFromPlot(QCustomPlot& plot)
{
    MSElementDescrP edp = nullptr;
    //...some code there
    return std::make_shared<EditElementHandle>(edp,true,false,ACTIVEMODEL);
}

主要是优雅、骨感(一个朋友经常用这个词评价代码)。。。
因为这样的限制,EditElementHandle也不能直接放入标准容器,所以MDLAPI提供了一个专用的容器ElementAgenda,同样,你思考一下,这个容器能不能以左值存在?下面的代码居然是可以通过编译的:

ElementAgenda getAgenda()
{
    return ElementAgenda();
}

非常符合编码的直觉和手感,但如果你以左值使用它,会导致系统的崩溃。因为接口并没有在dll中导出这两个函数:

ElementAgenda& operator == (ElementAgenda const&);
ElementAgenda(ElementAgenda const&);

它并不是个完整的类,mdl Api中大部分的类都不是完整的(暴力阉割),当你以左值使用它的时候,编译器会用默认的方式,按完整的类的声明的方式按字节拷贝,不完整的类的内存布局本身就是错的,这太危险了(汗流浃背。。。)

你可能已经猜到如何在左值的情况下使用它了。。。

相关文章

  • EditElementHandle用法和思考

    其实我不愿意写有关microstation的代码,有点专,有点窄,API有点糙,甚至很多与经典范式和准则都是背道而...

  • 何坤松:手机已统治了人类

    没用枪炮 没用法令 它已统治了人类 人类放弃了思考和挣扎 投降 跟着整齐的长队 走回洞穴

  • 定时器

    setTimeout和clearTimeout基本用法 setInterval和clearInterval基本用法...

  • 笔记类APP推荐:印象笔记

    1. 有什么用? 印象笔记用途 (整理和思考的工具) 印象笔记有很多用法,例如,写日记,随笔...

  • this,that和it用法

    英语有很多很细小的知识点,而这些细小的知识点往往就是考点。同学们很容易由于注意不到而犯错误,下面为大家分享this...

  • iOS 10 「就寝」功能的用法和思考

    不知道在什么时候开始,我们开始养成拿手机当做闹钟的习惯,很少会再到街角的礼品店买一个漂亮的闹钟放在床头点缀房间的同...

  • 慢思考的用法

    这两天的学习效果比较好。做法很简单。 我做到了两点:1 看见新知识不要着急着学会它更不要退缩,不学,跳过。否则学不...

  • Android 04 layer-list的用法总结

    Android layer-list的用法总结目录介绍 1.思考 2.layer-list代码实现效果 1.思考?...

  • 5_Linux进阶

    关键词:find的用法、grep的用法、file的用法、which和whereis的用法、gzip bzip2 t...

  • 181110读《多维度视角下的汉语修辞学》-1

    1、以下内容,帮助我重新理解“语言”,和语言的用法——“修辞”。 2、并让我重新思考“与君一席话,胜读十年书”和“...

网友评论

    本文标题:EditElementHandle用法和思考

    本文链接:https://www.haomeiwen.com/subject/riprdrtx.html