【问题标题】:Is it possible to cast object of class to void *?是否可以将类的对象转换为 void *?
【发布时间】:2011-02-24 03:52:00
【问题描述】:

我正在尝试使用 STL 中的qsort 对边缘数组进行排序:

struct edge
{
    int w,v,weight;
};

按重量计算。我正在尝试的是:

int compare_e(const void *a, const void *b)
{
    return ( *(edge *)a->weight - *(edge *)b->weight );
};

但我明白了:

`const void*' 不是 指向对象类型

编辑: 好的 thx,现在我的代码已编译,但排序似乎不能 100% 工作......

#include <cstdlib>
#include <iostream>


struct edge
{
    int w,v,weight;
};

struct edge_ID:edge
{
    int id;
};

int compare_e(const void *a, const void *b)
{
    return ( ((edge *)a)->weight > ((edge *)b)->weight );
};

int main()
{   
    using namespace std;

    edge *tab = new edge[100];

    for(int i = 0; i < 100; i++)
    {
        tab[i].weight = rand() % 100;
        cout << i << " => " << tab[i].weight << endl;
    }


    qsort(tab, 100, sizeof(edge), compare_e);

    cout << "AFTER:" << endl;
    for(int i = 0; i < 100; i++)
    {
        cout << i << " => " << tab[i].weight << endl;
    }


    system("PAUSE");
    return EXIT_SUCCESS;
}

我的号码放错地方了……

【问题讨论】:

  • 为什么不试试 std::sort 更容易
  • 排序是否只适用于迭代器?
  • 对于数组指针是迭代器
  • 比较函数还不正确。返回负数表示较小,0 表示相等,正数表示较大。

标签: c++ stl qsort


【解决方案1】:

你可以做到的:

int compare_e(const void *a, const void *b)
{
    return  ((edge *)a)->weight - ((edge *)b)->weight ;
}

但如果您正在编写 C++ 代码,我看不出这样做的任何理由 - 为什么需要使用此 compare_e 函数?

【讨论】:

    【解决方案2】:

    你需要((const edge *)a)-&gt;weight - ((const edge *)b)-&gt;weight

    【讨论】:

      【解决方案3】:

      您需要一个额外的括号,并且不应使用 * 取消引用您的指针

      ((edge *)a)->weight
      

      为了回答您的添加,您的compare_e 函数现在是错误的!保留减去两个权重的第一个版本。

      比较函数应该返回一个负数是A &lt; B,如果A == B返回0,如果A &gt; B返回一个正数。您可以使用if/else 来实现它,但return A - B 在大多数情况下都有效。

      【讨论】:

        【解决方案4】:

        不要使用 qsort,使用 std::sort:http://www.sgi.com/tech/stl/sort.html

        【讨论】:

          【解决方案5】:
          struct less_by_weight
          {
            bool operator()(const edge& lhs, const edge& rhs) const
            {
              return lhs.weight < rhs.weight;
            }
          };
          
          int main()
          {   
              const std::size_t size = 100;
              edge *tab = new edge[size];
          
              for(int i = 0; i < size; ++i)
              {
                  tab[i].weight = rand() % size;
                  std::cout << i << " => " << tab[i].weight << '\n';
              }
          
              std::sort( tab, tab+size, less_by_weight() ); 
          
              std::cout << "AFTER:" << '\n';
              for(int i = 0; i < size; ++i)
              {
                  std::cout << i << " => " << tab[i].weight << '\n';
              }
          
              return EXIT_SUCCESS;
          }
          

          【讨论】:

          • THX 它似乎可以工作......但无论如何你知道为什么我的 qsort 代码不能正常工作吗?
          • @MMM:不,我什至没看过。使用C++,我已经十多年没有使用qsort()了。 std::sort() 也更容易使用和更快(根据设计,因为对比较器的调用将被内联),所以我认为没有理由处理这样的代码。你也应该使用std::vector,而不是手动管理内存。
          【解决方案6】:

          在回答您的问题时,无法将对象强制转换为 void*。指针可以转换为void*,但不能转换为对象。也可以转换引用,但不能转换为 void*

          qsort 不是 C++ 标准模板库的一部分,它是标准 C 库的一部分,这是完全不同的。

          STL 绝对是使用惯用 C++ 的方式。 @sbi 的回答向您展示了如何将 std::sort 与指针数组一起使用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-29
            • 2021-02-25
            • 1970-01-01
            • 2011-06-17
            相关资源
            最近更新 更多