C++ 如何将对象*作为空*&;传递;?
我有以下代码:C++ 如何将对象*作为空*&;传递;?,c++,void,void-pointers,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"; } 其中,TCE如果为void*类型。 问题是我不知道如何将类型为Balloon*的对象b2作为void*&传递。
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";
}
其中,TCE如果为void*类型。
问题是我不知道如何将类型为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是我遇到问题的参数,但我不知道如何使其工作。您不能将
t*
类型的左值(其中t
不是void
)作为void*&
类型的参数传递。这是语言不允许的。仅仅因为任何数据指针类型都可以转换为void*
,并不意味着任何数据指针类型都可以转换为void*&
。这是完全不同的事情
如果您真的想这样做,您必须使用
reinterpret\u cast
强制转换到void*&
。然而,您似乎试图执行的操作实际上没有多大意义。即使您的代码可能会被强制“工作”,通过使用reinterpret\u cast
,它仍然是一种黑客行为。正如您的代码所述,您有一个气球类。您已经为两个气球实例动态分配了内存,并调用了它们的构造函数,用各自的数据填充它们。然后,将每个对象的地址存储到适当的原始指针中
此类型定义:
typedef void* TCE; // why?
这是毫无意义的。引用void*
(void*&
)也是毫无意义的。为什么?因为void*
只保存一个值—字节流的第一个字节(当您将任何内容解释为void*
时,它们的计数将丢失,这是因为计数依赖于类型)。所以,它已经是一个指针了。您传递的不是整个字节流,而是第一个字节的地址。然后在函数中进一步解释它
但是在这种情况下,没有必要这样解释它。当从一个非常低的层次分析引用时,它只是一个伪装的指针,使我们能够安全地获得指针的好处(不需要考虑太多)。还有很多,但就目前而言,这很重要
您可以:
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)
}
遵守第三条(亲爱的主…):
您还可以通过reinterpet_cast绕过所有编译器对类型检查的帮助,这是非常危险的,如果您必须使用它,那么您要么是大错特错,要么是遇到了非常严重的问题(这可能源于您的方法大错特错)。注意源代码周围的const
ness,这是一种很好的做法,无论何时,只要您希望复制的东西没有损坏
还要注意,在这些情况下会出现很多内存管理,这只是一个简单的情况 上帝啊,可怕的密码。@DeadMG,对吗?daknok编写了更好的代码:Đ您知道您的
testCopy
代码泄漏内存吗?具体来说,它泄漏了3个气球对象——两个在testCopy
中分配,一个在cpyBalloon
中分配。其中,第一行中分配的那一个似乎是最严重的泄漏,因为在testCopy
函数结束之前它已经无法访问。是的,我知道它仍然存在问题,但首先我想解决这个问题。糟糕的代码?将引出序号*指定给TCE&有什么问题?您总是可以创建一个转换构造函数或运算符,或者更好的是,创建一个TCE::operator=重载来编译并执行…好的,几乎任何您想要的操作。cpyBallon是copyBalloon的一个很好的缩写,因为它保存了两个键入字符,它们是三个O中的两个,这使得它特别容易记住。如果不清楚,“work”之所以用倒逗号,是因为生成的代码看起来可以工作,但按照标准不能保证工作。其中最主要的是严格的别名规则(这是一种表示“允许优化器破坏您的代码”的方式)。另一个理论上值得关注的事实是,对象*
的表示不需要与无效*
的表示相同,因此将对象*&
重新解释为无效*&
在形式上是不正确的。当安德烈说“这是一个黑客”时,他的意思是“不要这样做”。谢谢你,这真的帮了我很大的忙。我不太理解void*。再次感谢。
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...
}