用接口处理一个类? [英] Disposing a class with an interface?

查看:75
本文介绍了用接口处理一个类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

interface Bar{
}
class Foo: Bar{
    int i;
    this(int _i){
        i = _i;
    }
}

void main(){
    import std.experimental.allocator.mallocator;
    import std.experimental.allocator;
    auto f = Mallocator.instance.make!Foo(42);
    Bar b = f;
    Mallocator.instance.dispose(b);// Bad
}

我目前正在创建自己的智能指针,现在将其扩展为也可用于类和多态性。

I am currently creating my own smart pointer and I am now extending them to also work with classes and polymorphism.

我遇到的问题是子类型化,我正在将指针从 Box!Foo 转移到 Box!Bar 如果Foo实现了Bar。

The problem I am running into is subtyping, I am transferring a pointer from Box!Foo to Box!Bar if Foo implements Bar.

但是Box!Bar超出范围,调用在接口上进行处理,并且它

But then Box!Bar goes out of scope and calls dispose on the interface and it crashes.

如果我只有接口指针,该如何处置对象?

How do I dispose an object if I only have an interface pointer?

我想我可以只需将指针存储为 void *

I guess I could just store the pointer under the hood as void*.

使用 DMD64 D编译器编译v2.071.0

*** Error in `./bin/breeze_task': free(): invalid pointer: 0x00000000018196c0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f8491fa7725]
/lib/x86_64-linux-gnu/libc.so.6(+0x7ff4a)[0x7f8491faff4a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f8491fb3abc]
./bin/breeze_task(_D3std12experimental9allocator10mallocator10Mallocator10deallocateMOFNiAvZb+0x51)[0x498a6d]
./bin/breeze_task(_D3std12experimental9allocator77__T7disposeTOS3std12experimental9allocator10mallocator10MallocatorTC3app3BarZ7disposeFKOS3std12experimental9allocator10mallocator10MallocatorC3app3BarZv+0x73)[0x48f513]
./bin/breeze_task(_Dmain+0x39)[0x48f241]
./bin/breeze_task(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv+0x1f)[0x49de57]
./bin/breeze_task(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv+0x21)[0x49dda1]
./bin/breeze_task(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv+0x2b)[0x49de13]
./bin/breeze_task(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv+0x21)[0x49dda1]
./bin/breeze_task(_d_run_main+0x1d2)[0x49dd12]
./bin/breeze_task(main+0x20)[0x4901f0]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f8491f50830]
./bin/breeze_task(_start+0x29)[0x48f119]
======= Memory map: ========
00400000-00517000 r-xp 00000000 08:15 398722                             /home/maik/projects/breeze/bin/breeze_task
00717000-00718000 r--p 00117000 08:15 398722                             /home/maik/projects/breeze/bin/breeze_task
00718000-0072e000 rw-p 00118000 08:15 398722                             /home/maik/projects/breeze/bin/breeze_task
0072e000-0072f000 rw-p 00000000 00:00 0 
017fc000-0182e000 rw-p 00000000 00:00 0                                  [heap]
7f848c000000-7f848c021000 rw-p 00000000 00:00 0 
7f848c021000-7f8490000000 ---p 00000000 00:00 0 
7f8490c68000-7f8490c6d000 r-xp 00000000 08:12 141260                     /usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0
7f8490c6d000-7f8490e6c000 ---p 00005000 08:12 141260                     /usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0
7f8490e6c000-7f8490e6d000 r--p 00004000 08:12 141260                     /usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0
7f8490e6d000-7f8490e6e000 rw-p 00005000 08:12 141260                     /usr/lib/x86_64-linux-gnu/libXfixes.so.3.1.0
7f8490e6e000-7f8490fe0000 r-xp 00000000 08:12 132861                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f8490fe0000-7f84911e0000 ---p 00172000 08:12 132861                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f84911e0000-7f84911ea000 r--p 00172000 08:12 132861                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f84911ea000-7f84911ec000 rw-p 0017c000 08:12 132861                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f84911ec000-7f84911f0000 rw-p 00000000 00:00 0 
7f84911f0000-7f84912aa000 r-xp 00000000 08:12 416324                     /usr/lib/nvidia-364/libGLdispatch.so.0
7f84912aa000-7f84914aa000 ---p 000ba000 08:12 416324                     /usr/lib/nvidia-364/libGLdispatch.so.0
7f84914aa000-7f84914b9000 rw-p 000ba000 08:12 416324                     /usr/lib/nvidia-364/libGLdispatch.so.0
7f84914b9000-7f84914d9000 rw-p 00000000 00:00 0 
7f84914d9000-7f84914ea000 r-xp 00000000 08:12 416297                     /usr/lib/nvidia-364/libGLX.so.0
7f84914ea000-7f84916e9000 ---p 00011000 08:12 416297                     /usr/lib/nvidia-364/libGLX.so.0
7f84916e9000-7f84916ea000 rw-p 00010000 08:12 416297                     /usr/lib/nvidia-364/libGLX.so.0
7f84916ea000-7f849170a000 rw-p 00000000 00:00 0 
7f849170a000-7f8491713000 r-xp 00000000 08:12 141278                     /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
7f8491713000-7f8491912000 ---p 00009000 08:12 141278                     /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
7f8491912000-7f8491913000 r--p 00008000 08:12 141278                     /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
7f8491913000-7f8491914000 rw-p 00009000 08:12 141278                     /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
7f8491914000-7f8491925000 r-xp 00000000 08:12 141258                     /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f8491925000-7f8491b24000 ---p 00011000 08:12 141258                     /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f8491b24000-7f8491b25000 r--p 00010000 08:12 141258                     /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f8491b25000-7f8491b26000 rw-p 00011000 08:12 141258                     /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f8491b26000-7f8491b2b000 r-xp 00000000 08:12 141256                     /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f8491b2b000-7f8491d2a000 ---p 00005000 08:12 141256                     /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f8491d2a000-7f8491d2b000 r--p 00004000 08:12 141256                     /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f8491d2b000-7f8491d2c000 rw-p 00005000 08:12 141256                     /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f8491d2c000-7f8491d2e000 r-xp 00000000 08:12 141245                     /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f8491d2e000-7f8491f2e000 ---p 00002000 08:12 141245                     /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f8491f2e000-7f8491f2f000 r--p 00002000 08:12 141245                     /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f8491f2f000-7f8491f30000 rw-p 00003000 08:12 141245                     /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f8491f30000-7f84920f0000 r-xp 00000000 08:12 281619                     /lib/x86_64-linux-gnu/libc-2.23.so
7f84920f0000-7f84922ef000 ---p 001c0000 08:12 281619                     /lib/x86_64-linux-gnu/libc-2.23.so
7f84922ef000-7f84922f3000 r--p 001bf000 08:12 281619                     /lib/x86_64-linux-gnu/libc-2.23.so
7f84922f3000-7f84922f5000 rw-p 001c3000 08:12 281619                     /lib/x86_64-linux-gnu/libc-2.23.so
7f84922f5000-7f84922f9000 rw-p 00000000 00:00 0 
7f84922f9000-7f849230f000 r-xp 00000000 08:12 267115                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f849230f000-7f849250e000 ---p 00016000 08:12 267115                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f849250e000-7f849250f000 rw-p 00015000 08:12 267115                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f849250f000-7f8492516000 r-xp 00000000 08:12 281614                     /lib/x86_64-linux-gnu/librt-2.23.so
7f8492516000-7f8492715000 ---p 00007000 08:12 281614                     /lib/x86_64-linux-gnu/librt-2.23.so
7f8492715000-7f8492716000 r--p 00006000 08:12 281614                     /lib/x86_64-linux-gnu/librt-2.23.so
7f8492716000-7f8492717000 rw-p 00007000 08:12 281614                     /lib/x86_64-linux-gnu/librt-2.23.so
7f8492717000-7f849281f000 r-xp 00000000 08:12 281470                     /lib/x86_64-linux-gnu/libm-2.23.so
7f849281f000-7f8492a1e000 ---p 00108000 08:12 281470                     /lib/x86_64-linux-gnu/libm-2.23.so
7f8492a1e000-7f8492a1f000 r--p 00107000 08:12 281470                     /lib/x86_64-linux-gnu/libm-2.23.so
7f8492a1f000-7f8492a20000 rw-p 00108000 08:12 281470                     /lib/x86_64-linux-gnu/libm-2.23.so
7f8492a20000-7f8492a21000 r-xp 00000000 08:12 141239                     /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1.0.0
7f8492a21000-7f8492c20000 ---p 00001000 08:12 141239                     /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1.0.0
7f8492c20000-7f8492c21000 r--p 00000000 08:12 141239                     /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1.0.0
7f8492c21000-7f8492c22000 rw-p 00001000 08:12 141239                     /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1.0.0
7f8492c22000-7f8492c25000 r-xp 00000000 08:12 281620                     /lib/x86_64-linux-gnu/libdl-2.23.so
7f8492c25000-7f8492e24000 ---p 00003000 08:12 281620                     /lib/x86_64-linux-gnu/libdl-2.23.so
7f8492e24000-7f8492e25000 r--p 00002000 08:12 281620                     /lib/x86_64-linux-gnu/libdl-2.23.so
7f8492e25000-7f8492e26000 rw-p 00003000 08:12 281620                     /lib/x86_64-linux-gnu/libdl-2.23.so
7f8492e26000-7f8492e2f000 r-xp 00000000 08:12 141252                     /usr/lib/x86_64-linux-gnu/libXcursor.so.1.0.2
7f8492e2f000-7f849302e000 ---p 00009000 08:12 141252                     /usr/lib/x86_64-linux-gnu/libXcursor.so.1.0.2
7f849302e000-7f849302f000 r--p 00008000 08:12 141252                     /usr/lib/x86_64-linux-gnu/libXcursor.so.1.0.2
7f849302f000-7f8493030000 rw-p 00009000 08:12 141252                     /usr/lib/x86_64-linux-gnu/libXcursor.so.1.0.2
7f8493030000-7f8493032000 r-xp 00000000 08:12 141268                     /usr/lib/x86_64-linux-gnu/libXinerama.so.1.0.0
7f8493032000-7f8493231000 ---p 00002000 08:12 141268                     /usr/lib/x86_64-linux-gnu/libXinerama.so.1.0.0
7f8493231000-7f8493232000 r--p 00001000 08:12 141268                     /usr/lib/x86_64-linux-gnu/libXinerama.so.1.0.0
7f8493232000-7f8493233000 rw-p 00002000 08:12 141268                     /usr/lib/x86_64-linux-gnu/libXinerama.so.1.0.0
7f8493233000-7f84932a0000 r-xp 00000000 08:12 141103                     /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
7f84932a0000-7f84934a0000 ---p 0006d000 08:12 141103                     /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
7f84934a0000-7f84934a1000 r--p 0006d000 08:12 141103                     /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
7f84934a1000-7f84934a2000 rw-p 0006e000 08:12 141103                     /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1
7f84934a2000-7f849352f000 r-xp 00000000 08:12 416287                     /usr/lib/nvidia-364/libGL.so.1.0.0
7f849352f000-7f849372f000 ---p 0008d000 08:12 416287                     /usr/lib/nvidia-364/libGL.so.1.0.0
7f849372f000-7f8493730000 rw-p 0008d000 08:12 416287                     /usr/lib/nvidia-364/libGL.so.1.0.0
7f8493730000-7f8493731000 rw-p 00000000 00:00 0 
7f8493731000-7f849373b000 r-xp 00000000 08:12 141276                     /usr/lib/x86_64-linux-gnu/libXrandr.so.2.2.0
7f849373b000-7f849393a000 ---p 0000a000 08:12 141276                     /usr/lib/x86_64-linux-gnu/libXrandr.so.2.2.0
7f849393a000-7f849393b000 r--p 00009000 08:12 141276                     /usr/lib/x86_64-linux-gnu/libXrandr.so.2.2.0
7f849393b000-7f849393c000 rw-p 0000a000 08:12 141276                     /usr/lib/x86_64-linux-gnu/libXrandr.so.2.2.0
7f849393c000-7f8493941000 r-xp 00000000 08:12 141294                     /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1.0.0
7f8493941000-7f8493b40000 ---p 00005000 08:12 141294                     /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1.0.0
7f8493b40000-7f8493b41000 r--p 00004000 08:12 141294                     /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1.0.0
7f8493b41000-7f8493b42000 rw-p 00005000 08:12 141294                     /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1.0.0
7f8493b42000-7f8493c77000 r-xp 00000000 08:12 141241                     /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f8493c77000-7f8493e77000 ---p 00135000 08:12 141241                     /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f8493e77000-7f8493e78000 r--p 00135000 08:12 141241                     /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f8493e78000-7f8493e7c000 rw-p 00136000 08:12 141241                     /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f8493e7c000-7f8493e94000 r-xp 00000000 08:12 281618                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8493e94000-7f8494093000 ---p 00018000 08:12 281618                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8494093000-7f8494094000 r--p 00017000 08:12 281618                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8494094000-7f8494095000 rw-p 00018000 08:12 281618                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7f8494095000-7f8494099000 rw-p 00000000 00:00 0 
7f8494099000-7f84940a8000 r-xp 00000000 08:12 141266                     /usr/lib/x86_64-linux-gnu/libXi.so.6.1.0
7f84940a8000-7f84942a7000 ---p 0000f000 08:12 141266                     /usr/lib/x86_64-linux-gnu/libXi.so.6.1.0
7f84942a7000-7f84942a8000 r--p 0000e000 08:12 141266                     /usr/lib/x86_64-linux-gnu/libXi.so.6.1.0
7f84942a8000-7f84942a9000 rw-p 0000f000 08:12 141266                     /usr/lib/x86_64-linux-gnu/libXi.so.6.1.0
7f84942a9000-7f84942ca000 r-xp 00000000 08:12 142612                     /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f84942ca000-7f84944c9000 ---p 00021000 08:12 142612                     /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f84944c9000-7f84944ca000 r--p 00020000 08:12 142612                     /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f84944ca000-7f84944cb000 rw-p 00021000 08:12 142612                     /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f84944cb000-7f84944f1000 r-xp 00000000 08:12 281615                     /lib/x86_64-linux-gnu/ld-2.23.so
7f84945b6000-7f84946c3000 rw-p 00000000 00:00 0 
7f84946ed000-7f84946f0000 rw-p 00000000 00:00 0 
7f84946f0000-7f84946f1000 r--p 00025000 08:12 281615                     /lib/x86_64-linux-gnu/ld-2.23.so
7f84946f1000-7f84946f2000 rw-p 00026000 08:12 281615                     /lib/x86_64-linux-gnu/ld-2.23.so
7f84946f2000-7f84946f3000 rw-p 00000000 00:00 0 
7ffeb88e3000-7ffeb8904000 rw-p 00000000 00:00 0                          [stack]
7ffeb890f000-7ffeb8911000 r--p 00000000 00:00 0                          [vvar]
7ffeb8911000-7ffeb8913000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Program exited with code -6

这是处理函数:

void dispose(A, T)(auto ref A alloc, T p)
if (is(T == class) || is(T == interface))
{
    if (!p) return;
    auto support = (cast(void*) p)[0 .. typeid(p).init.length];
    destroy(p);
    alloc.deallocate(support);
}

问题似乎出在这行

auto support = (cast(void*) p)[0 .. typeid(p).init.length];



interface Bar{
}
class Foo: Bar{
    int i;
    this(int _i){
        i = _i;
    }
}

void main(){
    import std.experimental.allocator.mallocator;
    import std.experimental.allocator;
    auto f = Mallocator.instance.make!Foo(42);
    Bar b = f;
    auto support = (cast(void*) b)[0 .. typeid(b).init.length];
    writeln("length ", support.length);
    Mallocator.instance.dispose(b);// Bad
}

实际上它会打印 length 0 ,因为 typeid(b).init.length 也是0。看来这里是

It actually prints length 0 because typeid(b).init.length is also 0. It appears that something here is very wrong.

f b 来自 cast(void *)的信息不同,请参见如何获取具有接口的对象的地址?

Also the addresses of f and b from cast(void*) are different, see How do I get the address of an object with an interface?

推荐答案

好的,问题是我正在使用dub并将emsi_container作为依赖项。 emsi_container有一个过时的std.experimental.allocator版本作为依赖项,使编译器附带的版本黯然失色。

Okay the problem was that I was using dub and had emsi_container as a dependency. emsi_container has an outdated version of std.experimental.allocator as a dependency which overshadowed the version that ships with the compiler.

此错误已在最新版的std中修复。实验分配器。

This bug is fixed in the newest version of std.experimental.allocator.

这篇关于用接口处理一个类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆