Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将对象*作为空*&;传递;?_C++_Void_Void Pointers - Fatal编程技术网

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*
时,它们的计数将丢失,这是因为计数依赖于类型)。所以,它已经是一个指针了。您传递的不是整个字节流,而是第一个字节的地址。然后在函数中进一步解释它

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

您可以:

  • 在堆栈上创建实例(本地)并将其作为引用传入
  • 在堆上创建实例并获取内存地址,将它们传入并进一步处理
  • 或者。。。您可以执行操作过程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)
        }
    
    遵守第三条(亲爱的主…):

    您还可以通过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...
        }