c++ - 函数调用运算符重载和析构函数帮助

标签 c++ operator-overloading dynamic-memory-allocation disjoint-sets

我认为我的析构函数现在很好......但仍然不确定如何从 operator() 重载中调用 print_set。

它按应有的方式输出,但我觉得有一种简单的方法可以从函数调用重载中调用 print_set ......似乎无法按照我想要的方式得到它们......

头文件:

/**
 * disjoint_sets class declaration
 *
 */

#include<ostream>
#include<string>
#include<list>

class disjoint_sets 
{
public:

  disjoint_sets(int n); //n is the maximum int that can be in a set, so arrays need to be of size n+1
  ~disjoint_sets();

  bool make_set(int n);
  int find_set(int u);
  bool union_set(int u, int v);
  void print_set(std::ostream& out, int u); //e.g. { 1, 2, 4, 8, 10, }

  operator std::string(); //e.g. "{ { 1, 2, 4, 8, 10, }, { 3, 6, }, { 5, }, { 7, }, { 9, }, }"

private:
  typedef std::list<int>* listptr;

  int* p;       //parent array
  int* rank;    //rank array
  listptr* set; //array of pointers. Each set[i] is a pointer is to a list<int> containing the integers in the i'th set
  int size;     //the size i.e. maximum int that can be in a set

};

实现:

/**
 * disjoint_sets class implementation
 *
 */

#include <iostream>
#include <istream>
#include <sstream>
#include <string>
#include <list>

#include "disjoint.hpp"



/*********************
 * CONSTRUCTOR
 *********************/
disjoint_sets::disjoint_sets(int n)
{
  size = n;

  // initialize all arrays to same size (n+1)  
  p      =    new int[n+1];
  rank   =    new int[n+1];
  set    =    new listptr[n+1];

  // loop through set (array of pointers) and initialize
  //   each element to an empty list
  for (int i(1); i <= n; i++)
    {
      set[i] = new std::list<int>;
    }
}



/*********************
 * DESTRUCTOR
 *********************/
disjoint_sets::~disjoint_sets()
{
  delete[] p;
  delete[] rank;

  // delete each element in the set first, then delete the set.
  for(int i(1); i<size+1; i++)
    {
      set[i]->clear();  
    }
  delete[] set;
}



/*********************
 * MAKE_SET
 *********************/
bool disjoint_sets::make_set(int n)
{
  // if parent already exists
  if (p[n] != 0)
    {
      return false;
    }

  // else we need to make a set  
  else
    {
      // make itself the parent
      p[n] = n;

      // use push_front to add the int to front of set
      set[n]->push_front(n);

      return true;
    }
}



/*********************
 * FIND_SET
 ***********************/
int disjoint_sets::find_set(int u)
{
  while (u != p[u])
    {
      u = p[u];
    }

  // returns parent  
  return u;
}



/*********************
 * UNION_SET
 *********************/
bool disjoint_sets::union_set(int u, int v)
{
  // assign parents to u, v
  u = find_set(u);
  v = find_set(v);


  // return false if parent is 0, list is empty
  if (u == 0 or v == 0)
    {
      return false;
    }


  // if u's height is less than v's (not in same set)
  if (rank[u] < rank[v])
    {
      // point u's parent to v (merge them)
      p[u] = v;

      // splice u out
      (*set[v]).splice((*set[v]).end(), (*set[u]));

      return true;
    }

  // u's height is greater than or equal to v's height  
  else
    {
      // set v's parent to u
      p[v] = u;

      // splice v out
      (*set[u]).splice((*set[u]).end(), (*set[v]));

      return true;
    }


  // if ranks are equal
  if (rank[u] == rank[v])
    {
      // increment rank of u
      rank[u]++;

      return true;
    }
}



/*********************
 * PRINT_SET
 *********************/
void disjoint_sets::print_set(std::ostream& out, int u)
{
  // begin brace for set
  out << "{ ";

  // loop through with iter, seperate with comma
  for (std::list<int>::iterator iter((*set[u]).begin()); iter != (*set[u]).end(); iter++)
    {
      out << *iter << ", ";
    }

  // end brace for set
  out << "}";
}



/*********************
 * STRING CONVERSION
 *********************/
disjoint_sets::operator std::string()
{
  // sstream variable
  std::stringstream text; 


  // pointer to int array
  int *test;
  test = new int[size+1];


  // opening paren
  text << "{ ";


  // start main loop through the array
  for (int i(1); i <= (size + 1); i++)
    {

      // if the root is empty
      if (test[find_set(i)] == 0)
        {

          // set to anything != 0?
          test[find_set(i)] = 10;


          // check if list is empty
          if (set[i]->empty())
            {
              text << "";
            }


          else
            {
              // individual set opening parenthesis
              text << "{ ";

              // use iterator to loop through and load up the stringstream, separate w/ comma
              for (std::list<int>::iterator iter((*set[i]).begin()); iter != (*set[i]).end(); iter++)
                {
                  text << *iter << ", ";
                }

              // individual set closing parenthesis w/ proper punctuation
              text << "}, ";    
            }
        }  
    }

  // closing parenthesis
  text << "}";    

  delete[] test;  

  return text.str(); 
}

司机:

#include<iostream>

#include "disjoint.hpp"


int main() 
{
  using namespace std;

  disjoint_sets ds(12);

  for( int i=1; i <= 10; ++i)
    ds.make_set(i);

  ds.union_set(1,2);
  ds.union_set(2,4);
  ds.union_set(1,8);
  ds.union_set(3,6);
  ds.union_set(2,10);

  //{ { 1, 2, 4, 8, 10, }, { 3, 6, }, { 5, }, { 7, }, { 9, }, }
  cout << string(ds) << endl;
}

最佳答案

只关注析构函数:

// delete[] set; // need special conditions for this?

是的,需要先删除集合中的每一个元素,再删除集合。如果您对内存管理不感兴趣,请使用 std::shared_ptr

提示:如果您提出具体问题,您可能会得到更好的答案。

关于c++ - 函数调用运算符重载和析构函数帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6803467/

相关文章:

c++ - QtCharts——后台、前台显示

c++ - std::atomic::operator++ 真的按值返回吗?

c++ - 为什么 cout 在重载运算符 << 的友元函数中不起作用,它是一个 istream 运算符

c++ - (错误 C2678)错误 : No operator "<<" matches these operands

c - 对数组使用动态内存分配

c++ - calloc/malloc 比 C++ 中的 operator new 快吗

c++ - 为什么char数据的地址不显示?

c++ - 是否有可能为 *IN* KD 树中的节点找到 KNN?

c++ - 为什么提议的 `std::shared_ptr::operator[]` 以 `std::ptrdiff_t` 作为参数

c - 动态内存分配和 sizeof()