繁体   English   中英

是否有解决方案可以从“无效转换 int* 到 int”C++ 中转义?

[英]Is there a solutions to escape from 'invalid conversion int* to int' C++?

当我尝试编译我的代码时出现此错误。 我没有任何* (指针)并且不明白为什么我会得到这个。 我现在使用template 您也可以检查我的代码,请参阅:

#include <iostream>
#include <cstdlib>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;

template <class T>
class Set
{
public:
    T **p;
    int n;
    Set(){
    };
    Set(int n)
    {
        this->n = n;
        p = new T*[n];
    }
    ~Set()
    {
      if(p) delete []p; 
    }
    void setValues(T k,int l)
    {
        p = k;
        n = l;
    }
    void add(T k)
    {
        T p1;
        p1 = p;
        p = new T[n+1];
        p = p1;
        p[n+1] = k;
        n++;
    }
    void remove(T k)
    {
        T p1;
        int l =0;
        p1 = p;
        p = new T[n-1];
        for(int i=0;i<n;i++)
            if(p1[i]!=k) 
            {
                p[l] = p1[i];
                l++;
                n--;
            } 
    }
    void operator+(Set s)
    {
        for(int i=0;i<n;i++)
            p[i]+=s.p[i];
    }
    void operator-(Set s)
    {
        for(int i=0;i<n;i++)
            p[i]-=s.p[i];
    }
    void operator*(Set s)
    {
        for(int i=0;i<n;i++)
            p[i]*=s.p[i];
    }
    void show()
    {
        for(int i=0;i<n;i++)
            cout<<p[i]<<" | ";
    }
};
int main()
{
    Set<int> s1,s2;
    int arr[]={0,2,3,4,3,6};
    int n=6;
    float arr2[]={0.5,12.1,1.7,23.15};
    char arr3[]={'a','h','m','k','c','e'};
    s1.setValues(arr,n); // <------------- here is error;
    s1.show();

}

我在这条线上收到错误s1.setValues(arr,n); 这是setValues()方法:

void setValues(T k,int l)
{
    p = k;
    n = l;
}

我试图通过使用&来避免错误: s1.setValues(arr,&n)s1.setValues(arr,*n)

我还尝试在方法中更改它: void setValues(T k,int &l)void setValues(T k,int *l) in class: public: T **p; int *n; public: T **p; int *n; public: T **p; int &n; public: T **p; int &n;

在我的第一个版本中,我尝试使用: s1.setValues(arr,6)其中6是数组的长度。 但我也收到了错误;

编辑:我误读了 p 的类型,并且显然也向后读了错误。

该类用T作为 int 进行了初始化。 所有数组都衰减为指针,因此arrint*类型。 这意味着您不能将其作为 setValues 的第一个参数传入。

void setValues(T k, int l);

...

s1.setValues(arr, n); //arr is type int*, but k is of type int.

恐怕我不明白您的代码做得足够好,无法建议您如何修复它,但这就是编译器发出该错误的原因。

初步评论:由于您不使用 std::set 我想这是一个练习,并且不允许您使用 std::vector 这将大大促进 p 的管理

问题

这段代码有一些矛盾,还有一些还没有出现的错误,因为没有使用对应的模板成员函数:

  • 成员T** p被定义为指向 T 的指针的指针
  • 在构造函数中,你分配了一个指向 T 的指针数组,它确实会给你一个指向 T 指针的指针。
  • 但是在add()remove()您尝试使用 T 数组重新分配 p,这将为您提供T*而不是T** 此外,您显然想要添加或删除一个值而不是一个指针。
  • 但是在设置值中,不清楚是要设置单个值(签名中的T k建议)还是要设置数组中的所有值(长度参数int l建议)。 鉴于函数的名称有复数形式的Values ,我将假设第二种选择。

解决方法 第一步:编译。 但它不会真正起作用

你需要纠正:

T *p;  

并相应地使用p = new T[n]调整构造函数;

   auto p1 = p;

然后,您需要将函数定义更改为:

void setValues(T k[],int l)  // option 1 
void setValues(T *k,int l)   // or option 2 

好消息是代码将被编译

坏消息是它不会做你想做的事。 此外,函数的代码和其他一些问题会导致UB(意味着可能会发生很多不好的事情,包括内存损坏,崩溃等......)。

解决方案步骤2:数组、指针的赋值和3的规则

这段代码不是你期望它做的:

void setValues(T *k, int l)
{
    p = k;   // OUCH !!!!!! pointer copy and not copy of the array elements
    n = l;
}

目前,您不复制数组的元素,而是替换指针。 这有以下后果:

  • 首先你会泄漏内存,因为指向分配内存的指针丢失并且永远不会被释放。
  • 其次,您将使这个指针指向一个没有用new[]分配的数组,这可能会在您稍后delete[]这个指针时对您造成严重伤害。
  • 第三:您的类指向的数组可能会被数组的所有者删除,在这种情况下,您将使用悬空指针。

因此,您需要按如下方式调整您的代码:

void setValues(T k[],int l) // change signature
{
    if (n!=l) {          // if the size is the same, we'll reuse p, if not:
        delete[] p;            // avoid the memory to leek 
        p= new T[l];           // start with a fresh memory 
        n = l;                 // define new length
    }
    for (int i=0; i<l; i++) 
        p[i]=k[i];              // copy array elements one by one 
}

另一个重要的问题是3规则 这对您当前的main()不是问题,但很快就会变成:如果您在构造函数或析构函数中使用指针,则应该定义复制构造函数和赋值运算符。 如果不这样做,则可能会以 Set 的浅拷贝(2 个不同的对象,但使用相同的指针)结束。

解决方案第 3 步:摆脱剩余的问题

首先,您的默认构造函数使 p 和 n 未初始化。 它们可能是随机值,这可能会导致析构函数尝试删除未分配的内容。 对于 anny 其他函数也是如此,它假定假定成员值的事物是一致的。 所以:

Set(){ 
    p=nullptr; 
    n=0; 
};

然后你在add()遇到了类似的问题,你在setValues()使用了指针赋值。 此外,即使在重新定位之后,您也会越界:具有n+1元素的数组 p 的最后一个元素是p[n]而不是 p[n+1]。 我让你作为练习来改进它。

在线演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM