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

时间:2012-06-05 19:51:16

标签: c++ void void-pointers

我有以下代码:

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;
}

其中TCE if类型为void *。 问题是我不知道如何传递Balloon *类型的对象b2为void *&amp ;.我一直收到以下错误:

    ..\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是我遇到问题的论据,但我不知道如何使其发挥作用。

2 个答案:

答案 0 :(得分:1)

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

此typedef:

typedef void* TCE; // why?

毫无意义。对void*void*&)的引用也毫无意义。为什么?因为void*只保存一个值 - 字节流的第一个字节(当你将任何东西解释为void*时,它们的计数会丢失,因为count是依赖于类型的)。所以,它已经是一个指针。您没有传递整个字节流,只传递第一个字节的地址。然后你可以根据自己的喜好在函数中进一步解释它。

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

你可以:

  1. 在堆栈上创建实例(本地)并将其作为参考传递。
  2. 在堆上创建实例并获取内存地址,将其传入并进一步处理。
  3. 或者......你可以采取行动2并将它们转换为void*,然后撤消功能中的强制转换(无论做什么好事)。
  4. 首先观察:

        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,只要您想要复制和完好无损的内容,这是一种很好的做法。

    另请注意,在这些情况下会出现大量内存管理,这只是一个简单的情况。

答案 1 :(得分:0)

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

如果您确实想这样做,则必须使用void *&强制转换为reinterpret_cast。然而,你似乎试图进行的操作并没有多大意义。即使您的代码可能强制使用reinterpret_cast“工作”,它仍然是一个黑客。