如何将对象*传递为void *&?

问题描述 投票:0回答:2

我有以下代码:

void testCopy(){
   Balloon* b1=new Balloon(1,5,6,3);
   Balloon* b2=new Ballon(2,4,4,2);
   cpyBallon(b1,b2);
   assert(b1->getCenterx()==5);
   cout<<" cpyBalloon() OK!\n";
}

并且cpyBalloon()的代码是

void cpyBalloon(TCE& dest,TCE src){
    Balloon* b=(Balloon*) src;
    Balloon* d=new Balloon();
    *d=*b;
    dest=d;
}

如果类型为void *,则为TCE。 问题是我不知道如何将类型为Balloon *的对象b2传递为void *&。 我不断收到以下错误:

    ..\src\/Domain/BalloonTest.h:68:18: error: invalid initialization of reference of type 'void*& {aka void*&}' from expression of type 'domain::Balloon*'
    ..\src\/Domain/Balloon.h:102:10: error: in passing argument 1 of 'void domain::delBalloon(void*&)'    

我知道b2是我遇到问题的理由,但我不知道如何使它起作用。

c++ void void-pointers
2个回答
1
投票

如代码所示,您有一个Balloon类。 您已经为两个Balloon实例动态分配了内存,并调用了它们的构造函数,并用各自的数据填充了它们。 然后,您将每个对象的地址存储到正确的原始指针中。

此typedef:

typedef void* TCE; // why?

是没有意义的。 对void*void*& )的引用也是没有意义的。 为什么? 因为void*仅保留一个值-字节流的第一个字节(当您将任何内容解释为void* ,它们的计数会丢失,这是因为count是与类型相关的)。 因此,它已经是一个指针。 您不会传递整个字节流,而只是传递第一个字节的地址。 然后,您可以根据需要在函数中进一步解释它。

但是在这种情况下,没有必要如此解释。 从非常低的层次进行分析时,引用只是变相的指针,使我们能够安全地获得指针的好处(无需过多考虑)。 还有更多,但是就目前而言,这很重要。

您可以:

  1. (在本地)在堆栈上创建实例,并将其作为参考传递。
  2. 在堆上创建实例并获取内存地址,将其传递并进一步处理。
  3. 或者...您可以采取行动2并将其强制转换为void* ,然后撤消函数中的强制转换(无论会做些什么)。

首先观察:

    Balloon b1(1,5,6,3);
    Balloon b2(2,4,4,2);

    cpyBalloon(b1, b2);

    void cpyBalloon(Balloon& dest, const Balloon& src) 
    {
        dest = src; // invokes the assignment copy operator (imp. generated)
    }

观察第二:

    Balloon* b1 = new Balloon(1,5,6,3);
    Balloon* b2 = new Balloon(2,4,4,2);

    cpyBalloon(b1, b2);

    void cpyBalloon(Balloon* dest, const Balloon* src) 
    {
        *dest = *src; // invokes the assignment copy operator (imp. generated)
    }

观察第三(亲爱的主...):

    Balloon* b1 = new Balloon(1,5,6,3);
    Balloon* b2 = new Balloon(2,4,4,2);

    cpyBalloon((void*)b1, (void*)b2);

    void cpyBalloon(void* dest, const Balloon* src) 
    {
        *(Balloon*)dest = *(const Balloon*)src; // oh god...
    }

您也可以reinterpet_cast来规避所有编译器的类型检查,这非常危险,如果必须使用它,则说明您错了或者遇到了非常讨厌的问题(可能是由于您的方法非常错误 )。 注意const周围的源湖,这就是每当你想要的东西复制和完好的很好的做法。

还要注意,在这些情况下会发生很多内存管理,这只是一个简单的情况。


0
投票

您不能将T*类型的左值(其中T不是void )作为类型void *&的参数传递。 语言不允许这样做。 仅仅因为任何数据指针类型都可以转换为void *并不意味着任何数据指针类型都可以转换为void *& 。 这些是完全不同的东西。

如果确实要执行此操作,则必须使用reinterpret_cast将转换强制为void *& 。 但是,您似乎试图执行的操作并没有多大意义。 即使您的代码可能由于使用reinterpret_cast被迫 “工作”,它仍然是一个hack。

© www.soinside.com 2019 - 2024. All rights reserved.