我有以下代码:
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是我遇到问题的论据,但我不知道如何使其发挥作用。
答案 0 :(得分:1)
正如您的代码所述,您有一个Balloon类。您已为两个Balloon实例动态分配内存并调用它们的构造函数,并使用相应的数据填充它们。然后,将每个对象的地址存储到适当的原始指针中。
此typedef:
typedef void* TCE; // why?
毫无意义。对void*
(void*&
)的引用也毫无意义。为什么?因为void*
只保存一个值 - 字节流的第一个字节(当你将任何东西解释为void*
时,它们的计数会丢失,因为count是依赖于类型的)。所以,它已经是一个指针。您没有传递整个字节流,只传递第一个字节的地址。然后你可以根据自己的喜好在函数中进一步解释它。
但在这种情况下,没有必要将其解释为这样。从非常低的层次进行分析时,引用只是伪装的指针,使我们能够安全地获得指针的好处(而不必过多考虑)。还有更多内容,但就目前而言,这很重要。
你可以:
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
,只要您想要复制和完好无损的内容,这是一种很好的做法。
另请注意,在这些情况下会出现大量内存管理,这只是一个简单的情况。
答案 1 :(得分:0)
您无法将类型T*
(其中T
不是void
)的左值作为void *&
类型的参数传递。语言不允许这样做。仅仅因为任何数据指针类型都可以转换为void *
并不意味着任何数据指针类型都可以转换为void *&
。这些是完全不同的东西。
如果您确实想这样做,则必须使用void *&
强制转换为reinterpret_cast
。然而,你似乎试图进行的操作并没有多大意义。即使您的代码可能强制使用reinterpret_cast
“工作”,它仍然是一个黑客。