对于这个程序,我想创建一个SET类,它包含一组数字正数且没有重复数。在我创建了SET类之后,我为+和*创建了重载运算符,将两个集合在一起,并分别找到两个集合的交叉数。然而,在我开始测试代码之后,我注意到+和*重载的运算符不能在包含数字的两个集合上工作,除非我创建了一个新的SET来输出数据。例如,我必须这样做:
SET set3 = set1 + set2;
cout << set3;
而不是只做:
cout << set1 + set2;
只有当两个集合都为空或者1个集合已填满且另一个集合为空时,我才能输出上述代码。我不确定我做错了什么,所以无法输出两个填充集。我将代码分成三个文件。 这是头文件:
//CSCI 205
//Brett Milinski
//Assignment 2 - The Set Class
//This problem wants us to create a set class to hold a mathematical set of integers and can later be manipulated to implement the Sieve of Eratosthenes method for computing prime numbers
#ifndef SET_H
#define SET_H
#include<iostream>
using namespace std;
class SET
{
private: int a[50];
int length;
const int SIZE = 50;
public: SET();
SET(int a, int b);
void print(ostream &os);
void insert(int x);
void erase(int x);
int searchList(int a[], int length, int x);
int addSearchList(int a[], int length, int x);
friend SET& operator+(SET& a, SET& b);
friend SET& operator*(SET& a, SET& b);
friend ostream& operator<<(ostream& os, SET& a);
SET& sieveOfEratosthenes(int n);
};
#endif
这是定义方法的set.cpp文件:
//CSCI 205
//Brett Milinski
//Assignment 2 - The Set Class
//This problem wants us to create a set class to hold a mathematical set of integers and can later be manipulated to implement the Sieve of Eratosthenes method for computing prime numbers
#include"set.h"
#include<iostream>
using namespace std;
SET::SET() //default constructor
{
length = 0;
}
SET::SET(int start, int end) //overloaded constructor
{
length = end - start + 1; //end of range of numbers to be input
if (length <= SIZE) //range isn't too big for the array
{
for (int x = 0; x < length; x++)
{
a[x] = start;
start++;
}
}
}
void SET::insert(int x) //function to insert numbers from the array
{
bool inserted = false;
for (int i = 0; i < length; i++) //check to see if the value is already in the set, if so, don't add
{
if (a[i] == x)
{
inserted = true;
cout << "Sorry, the SET already contains that number." << endl;
}
}
if (inserted == false) //the SET does not contain the number that is trying to be inserted
{
int check = addSearchList(a, length, x); //check the position of where to add the value
if (length == SIZE) //check to see if the array is already full
{
cout << "You cannot add anymore elements to this array because it is full." << endl;
}
else if (check == length) //check to see if it is added at the end
{
length++; //make the array one size bigger to make room for the addition
a[length - 1] = x; //add the value to the end
}
else
{
length++; //make the array one size bigger to make room for the addition
for (int i = length - 1; i >= check; i--) //start at the bottom and move up towards where the new value should be
{
a[i] = a[i - 1]; //ripple down
}
a[check] = x; //add in the new value
}
}
}
void SET::erase(int x) //function to erase numbers from the array
{
int check = searchList(a, length, x); //check to see what the position is
if (length == 0) //check to see if the array is empty before deleting anything
{
cout << "The array is empty and therefore nothing can be deleted from the elements." << endl;
}
else if (check != -1) //check to see if the value is found
{
for (int x = check; x < length - 1; x++)
{
a[x] = a[x + 1]; //ripples every element up
}
length--; //makes the array one size smaller to accomadate the deletion
}
else
{
cout << "The value entered is not in the array." << endl; //the value being checked for does not exist
}
}
void SET::print(ostream &os) //function to output the values of the array
{
os << "The contents of the set are:" << endl;
for (int x = 0; x < length; x++)
{
os << a[x] << " ";
}
os << endl;
}
int SET::searchList(int a[], int length, int x) //a search for the erase function
{
int index = 0; // Used as a subscript to search array
int position = -1; // Used to record position of search value
bool found = false; // Flag to indicate if the value was found
while (index < length && a[index] <= x && !found)
{
if (a[index] == x) // If the value is found
{
found = true; // Set the flag
position = index; // Record the value's subscript
}
index++; // Go to the next element
}
return position; // Return the position, or -1
}
int SET::addSearchList(int a[], int length, int x) //a search for the insert function
{
int index = 0; // Used as a subscript to search array
int position = -1; // Used to record position of search value
while (index < length && a[index] <= x)
{
index++; // Go to the next element
}
if (index == length) //all the values were smaller than the number trying to be added
{
position = length; //position is at the end of the array
}
else
{
position = index; //found where to add the new element
}
return position; // Return the position, or currentSize
}
//calls the print function to print to the output stream
ostream& operator<<(ostream& os, SET& a)
{
a.print(os);
return os;
}
//join the two sets together
SET& operator+(SET& a, SET& b)
{
SET added;//empty set to add to
if (a.length == 0 && b.length != 0) //for empty sets
{
return b;
}
else if (b.length == 0 && a.length != 0) //for empty sets
{
return a;
}
else
{
for (int x = 0; x < a.length; x++) //add in the elements from the first set
{
added.insert(a.a[x]);
cout << added.a[x] << endl;
}
for (int x = 0; x < b.length; x++) //add in the elements from the second set
{
added.insert(b.a[x]);
cout << b.a[x] << endl;
}
return added; //returns the added set
}
}
//find what the two sets have in common
SET& operator*(SET& a, SET& b)
{
int shortestLength = 0;
SET inCommon;
if (a.length < b.length) //find the shortest length
{
shortestLength = a.length;
}
else
{
shortestLength = b.length;
}
//search through and find the highest common number between the sets
for (int x = 0; x < shortestLength; x++)
{
for (int i = 0; i < shortestLength; i++)
{
if (a.a[i] == b.a[x]) //see if it shares it and has it in common
{
inCommon.insert(a.a[i]); //put in the shared value
}
}
}
return inCommon; //return the common numbers
}
这是测试先前定义的不同方法的setTest.cpp:
//CSCI 205
//Brett Milinski
//Assignment 2 - The Set Class
//This problem wants us to create a set class to hold a mathematical set of integers and can later be manipulated to implement the Sieve of Eratosthenes method for computing prime numbers
#include"set.h"
#include<iostream>
using namespace std;
int main()
{
int dummy = 0;
SET set1(1, 7); //overloaded constructor
SET set2, set4; //default constructor
SET set3(5, 10);
SET set7(9, 11);
//testing the functions of the SET class (overloaded constructor)
cout << set1;
cout << "Insert 5:" << endl;
set1.insert(5); //try inserting to end
cout << set1;
cout << "Try insertering 5 again:" << endl;
set1.insert(5); //try inserting a duplicate number
cout << set1;
cout << "Insert 0:" << endl;
set1.insert(0); //try inserting to start
cout << set1;
cout << "Erase 3:" << endl;
set1.erase(3); //try erasing from middle
cout << set1;
cout << "Insert 3:" << endl;
set1.insert(3); //try inserting to the middle
cout << set1;
cout << "Erase 0:" << endl;
set1.erase(0); //try erasing from the start
cout << set1;
cout << "Erase 5:" << endl;
set1.erase(5); //try erasing from the end
cout << set1;
cout << "Erase 20 (shouldn't work because it isn't there):" << endl;
set1.erase(20); //try erasing something that isn't there
cout << set1;
cout << "Add to the empty set (set2) and then erase from it:" << endl;
set2.insert(1); //try adding to the empty set
cout << set2;
set2.erase(1); //try erasing from the now populated set
cout << set2;
//test second set (default constructor)
cout << "This is the default constructor (an empty set, should contain no values)." << endl;
cout << set2;
//try adding two overlapping sets together
cout << "Try adding two overlapping sets together:" << endl;
cout << "The First Set:" << endl;
cout << set1;
cout << "The Other Set:" << endl;
cout << set3;
cout << "After adding the sets together together:" << endl;
SET set5 = set1 + set3;
cout << set5;
//try adding two empty sets
cout << "Try adding two empty sets together:" << endl;
cout << "The First Set:" << endl;
cout << set2;
cout << "The Other Set:" << endl;
cout << set4;
cout << "After adding the sets together together:" << endl;
cout << set2 + set4;
//try adding one filled set and one empty set
cout << "Try adding one filled set and one empty set together:" << endl;
cout << "The First Set:" << endl;
cout << set1;
cout << "The Other Set:" << endl;
cout << set2;
cout << "After adding the sets together together:" << endl;
cout << set1 + set2;
//try adding two sets that don't overlap
cout << "Try adding two sets that don't overlap:" << endl;
cout << "The First Set:" << endl;
cout << set1;
cout << "The Other Set:" << endl;
cout << set7;
cout << "After adding the sets together together:" << endl;
cout << set1 + set7;
//find out what the sets have in common
cout << "Find what the two sets have in common:" << endl;
cout << "The First Set:" << endl;
cout << set1;
cout << "The Other Set:" << endl;
cout << set3;
SET set6 = set1 * set3;
cout << "The number that the two sets have in common is contained in the set below (if 0, there is no common number unless it is 0)" << endl;
cout << set6;
cout << "Enter a dummy number:" << endl;
cin >> dummy;
return 0;
}
我不确定为什么我无法做我想做的事,提前感谢我对问题的任何帮助!
答案 0 :(得分:2)
这两个功能
SET& operator+(SET& a, SET& b);
SET& operator*(SET& a, SET& b);
返回对临时对象的引用:
SET& operator+(SET& a, SET& b)
{
SET added;
// ...
return added; // <= temporary object returned via a reference - don't!!
}
这些临时对象(added
和inCommon
)通常由编译器在堆栈上分配,并且&#34;消失&#34;当控制流离开它们定义的函数时,你最终会得到悬空引用。这是一个非常讨厌的错误。
要解决此问题,请确保按值而不是按引用返回这些对象。所需要的只是更改返回类型:
SET operator+(SET& a, SET& b);
SET operator*(SET& a, SET& b);
^^^
no more references here
答案 1 :(得分:1)
除问题mentioned by @WhiteViking外,您的
声明//Populate Currently Allocated Reasource for each customer
for (i = 0; i < NUMBER_OF_CUSTOMERS; i++)
{
printf("%d:[ ",i);
for (j = 0; j < NUMBER_OF_RESOURCES; j++)
{
allocation[i][j] = maximum[i][j] ? (rand() % maximum[i][j]) : 0;
printf("%d ",allocation[i][j]);
}
printf("] \n\n");
}
应该是
friend ostream& operator<<(ostream& os, SET& a);
因为否则您将无法将rvalues(即临时对象)绑定到参数friend ostream& operator<<(ostream& os, const SET& a);
。在代码的第a
行中,std::cout << set1 + set2;
的第二个参数是右值operator<<
,它只能绑定到右值引用或set1 + set2
引用。实施这些更改后,您就可以使用const
而不会出现任何问题。