Use unique_ptr with struct and AcDbObjectPointer<AcDbLine> correctly ?

Use unique_ptr with struct and AcDbObjectPointer<AcDbLine> correctly ?

trithuongle
Advocate Advocate
2,871 Views
12 Replies
Message 1 of 13

Use unique_ptr with struct and AcDbObjectPointer<AcDbLine> correctly ?

trithuongle
Advocate
Advocate

Good morning everyone , i 'm writting a program to draw some frames . Inside it i 'm using C++ Smartpointer unique_ptr with struct  .then inside this struct i have some ObjectARX Smartpointer AcDbObjectPointer<AcDbLine> like below. Is there any problems with this kind of using ? 

Thanks in advance !

trithuongle_0-1660013570835.png

 

0 Likes
Accepted solutions (3)
2,872 Views
12 Replies
Replies (12)
Message 2 of 13

daniel_cadext
Advisor
Advisor
Accepted solution

 

Yeah,  they will be destructed, but your intent isn’t clear. 

If you’re just creating the lines, then you can just use some AcGePoint3d, AcGeVector3d or even AcGeLineSeg3d

If you need to track the objects over time, it’s better to store the ObjectId

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 3 of 13

tbrammer
Advisor
Advisor
Accepted solution

Bear in mind that AcDbObjectPointers can't be copied:

template<class T_OBJECT> class AcDbObjectPointer {
    // Copy and assignment prohibited.
    AcDbObjectPointer(const AcDbObjectPointer &) = delete;
    AcDbObjectPointer& operator=(const AcDbObjectPointer &) = delete;
};

Thus an instance of your struct standard can't be copied. This won't compile:

standard s1;
standard s2 = s1; //error C2280: standard::standard(const standard&): Tried to use a deleted function

Could it be that this is the reason why you want to use unique_ptrs?

 

I agree with @daniel_cadext: Using AcDbObjectPointers with unique_ptrs will "work". 

But I think it is dangerous because it might foil the intend of the AcDbObjectPointer: To close an object as soon as the AcDbObjectPointer is deleted. This might especially happen if you copy the unique_ptr that points to the struct with AcDbObjectPointers. This will postpone the deletion to the point where all unique_ptrs are out of scope. 

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 4 of 13

trithuongle
Advocate
Advocate

@daniel_cadext Thanks for your reply.

Sorry for my explanation is not clear enough.

My intent is i want to draw a group of lines (like a frame) but i don't want to remember about close or delete these lines .

Then , i also want  this group of lines has a few accompanying information to reuse after (height & angle).

So that i chose the struct to store AcDbObjectPointer<AcDbLine> and some above information .

Then in turn the struct-type object , i want to dynamic allocate this by smartpointer . So that i decided to use unique_ptr .

 

0 Likes
Message 5 of 13

trithuongle
Advocate
Advocate

@tbrammer Thanks for your reply .

There 's 1 thing in your reply that i haven't understand yet .

"___This might especially happen if you copy the unique_ptr that points to the struct with AcDbObjectPointers. This will postpone the deletion to the point where all unique_ptrs are out of scope."

I hope that you can make it more detail or give me a code example .

Thanks in advance !

0 Likes
Message 6 of 13

tbrammer
Advisor
Advisor

I didn't consider that a unique_ptr  can't  be copied - just like an AcDbObjectPointer. So my statement doesn't make sense. It would make sense for shared_ptrs. Sorry for that and thanks for pointing it out.

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 7 of 13

daniel_cadext
Advisor
Advisor

FYI, new headers have a definition DBOBJPTR_EXPOSE_PTR_REF that enables ref counting

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 8 of 13

daniel_cadext
Advisor
Advisor

Also you can create a custom delete for std::unique_ptr, kind of handy sometimes I.e.

template <class T>
class DBObjectDeleter
{
public:
    inline void operator()(T *p)
    {
        if (p != nullptr)
            return this->close(p);
    }
private:
    inline void close(T *p)
    {
        if (!p->objectId().isNull())
            p->close();
        else
            this->deleter(p);
    }
    inline void deleter(T *p)
    {
        delete p;
        p = nullptr;
    }
};

template<typename T>
using unique_dbo_ptr = std::unique_ptr<T, DBObjectDeleter<T>>;
using AcDbLineUPtr = unique_dbo_ptr<AcDbLine>;

//usage
AcDbLineUPtr ptr(new  AcDbLine({ 0,0,0 }, { 100, 100, 100 }));
Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 9 of 13

trithuongle
Advocate
Advocate

@tbrammer  sorry for late reply .

so that i think i can understand it.

Again, thank for your explanation !

0 Likes
Message 10 of 13

trithuongle
Advocate
Advocate

@daniel_cadext Sorry for late reply.

Can you explain more about "DBOBJPTR_EXPOSE_PTR_REF" with example ? 

Thanks in advance !

0 Likes
Message 11 of 13

trithuongle
Advocate
Advocate

@daniel_cadext Thank for your suggestion .

So that i think with this custom class . We could use it instead of "AcDbObjectPointer<AcDbLine>" sometimes.

Nice solution !

But let me confirm again about this .

According to your custom class ,i think your intent is create a custom deleter in unique_ptr .So that when the unique_ptr object goes out of its scope , it call the deleter , then if the internal pointer is not null then close the internal pointer , else just delete it ?

This is quite similar to ObjectARX 's AcDbObjectPointer <T class>right ?

0 Likes
Message 12 of 13

daniel_cadext
Advisor
Advisor
Accepted solution
Right, I only use the custom class for new objects, and when I want to use the entity's constructor, otherwise I use AcDbObjectPointer and the objectId.

DBOBJPTR_EXPOSE_PTR_REF is better explained here,
https://www.keanw.com/2008/04/automatic-closi.html
https://help.autodesk.com/view/OARX/2023/ENU/?guid=OARX-RefGuide-AcDbSmartObjectPointer
I may have incorrectly assume that this would add reference counting, to act more like a shared pointer
Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 13 of 13

trithuongle
Advocate
Advocate

@daniel_cadext Thank you alot for detailed instructions . i will continue to work on it .

Sincerely !

 

 

0 Likes