I'm learning to create sets in C++. I wrote this program that has some bugs in it because it's not fully done but that's not my main concern right now. I used a .h file to declare some functions and I defined them in my .cpp file. My compiler has given me a few errors.
1>SetMain.obj : error LNK2005: "public: __cdecl Set::Set(class Set const &)" (??0Set@@QEAA@AEBV0@@Z) already defined in Set.obj
1>SetMain.obj : error LNK2005: "public: __cdecl Set::Set(void)" (??0Set@@QEAA@XZ) already defined in Set.obj
1>SetMain.obj : error LNK2005: "public: __cdecl Set::~Set(void)" (??1Set@@QEAA@XZ) already defined in Set.obj
1>SetMain.obj : error LNK2005: "public: bool __cdecl Set::insert(int)" (?insert@Set@@QEAA_NH@Z) already defined in Set.obj
1>SetMain.obj : error LNK2005: "public: bool __cdecl Set::isElement(int)" (?isElement@Set@@QEAA_NH@Z) already defined in Set.obj
1>SetMain.obj : error LNK2005: "public: void __cdecl Set::print(void)" (?print@Set@@QEAAXXZ) already defined in Set.obj
1>SetMain.obj : error LNK2005: "public: bool __cdecl Set::remove(int)" (?remove@Set@@QEAA_NH@Z) already defined in Set.obj
1>C:\Users\OmarA\source\repos\Set\x64\Debug\Set.exe : fatal error LNK1169: one or more multiply defined symbols found
I looked up the errors but I still don't understand what I did wrong.
My .h file
#pragma once
#include <stdio.h>
class Set
{
int elementNum;
int* pData;
public:
// Initialize an empty set.
Set();
// Write a copy constructor. Do not forget the dynamically allocated attributes!
Set(const Set& theOther);
// Write a destructor: release dynamically allocated resources.
~Set();
// Insert a new element into the set. If no memory can be allocated, false is to be returned.
// If the set contains some element, then the same element cannot be inserted again;
// in this case the method should return true indicating that the element is already there in the set.
bool insert(int element);
// Remove an element from the set.
// If there is no such element in the set, then the method should return flase.
bool remove(int element);
// Check if the given element is contained by the set.
bool isElement(int element);
// Print the set elements separated by spaces. Puts a new line before the first an after the last elements.
void print();
};
My .cpp file:
#include "Set.h"
#include <limits.h>
#include <iostream>
Set::Set()
{
elementNum = 0;
pData = new int[elementNum];
}
Set::Set(const Set& theOther)
{
elementNum = theOther.elementNum;
pData = new int[elementNum];
for (int i = 0; i < elementNum; i++)
{
pData[i] = theOther.pData[i];
}
}
Set::~Set()
{
elementNum = 0;
delete[] pData;
}
bool Set::insert(int element)
{
if (elementNum > INT_MAX)
{
return false;
}
if (isElement(element))
{
return false;
}
int* ptrTemp = new int[elementNum+1];
for (int i = 0; i < elementNum; i++)
{
ptrTemp[i] = pData[i];
}
ptrTemp[elementNum] = element;
elementNum++;
delete[] pData;
pData = new int[elementNum];
for (int i = 0; i < elementNum; i++)
{
pData[i] = ptrTemp[i];
}
delete[] ptrTemp;
return true;
}
bool Set::remove(int element)
{
if (!isElement(element))
{
printf("No such element exists in the set\n");
return false;
}
int* ptrTemp = new int[elementNum-1];
for (int i = 0, j = 0; i < elementNum; i++, j++)
{
if (element == pData[i])
{
j--;
}
else
{
ptrTemp[j] = pData[i];
}
}
elementNum--;
pData = new int[elementNum];
for (int i = 0; i < elementNum; i++)
{
pData[i] = ptrTemp[i];
}
delete[] ptrTemp;
return true;
}
bool Set::isElement(int element)
{
for (int i = 0; i < elementNum; i++)
{
if (element == pData[i])
{
return true;
}
}
return false;
}
void Set::print()
{
for (int i = 0; i < elementNum; i++)
{
std::cout << pData[i];
}
}
My main file
#include "Set.cpp"
void printSet(Set s);
void printSet(Set* ps);
void printSet(Set s)
{
s.print();
}
void printSet(Set* ps)
{
ps->print();
}
int main(void)
{
Set s1; // a Set object is created
// Insert is tested
s1.insert(1);
s1.insert(1); // Inserting a duplicated element, the total number of elements should not change at this line
s1.insert(2);
s1.print();
// Testing isElement method
if (s1.isElement(1) && s1.isElement(2) && !s1.isElement(3))
{
printf("isElement seems OK.\n");
}
// Put a breakpoint here and observe the copy constructor calls
// Testing a copy constructor
Set s2(s1); // Explicit copy constructor call
Set s3 = s1; // Copy constructor is called by initialization
printSet(s1); // The parameter is passed by value -> copy is created -> copy constructor is called
printSet(s2); // The parameter is passed by value -> copy is created -> copy constructor is called
printSet(&s3); // The address of set object is passed -> copy constructor is NOT called
s2.remove(1); // Testing remove method
printSet(s2); // Checking the result of remove operation
printSet(s1); // Making sure that the other set object remained unchanged (if not -> problems in copy constructor)
s2.remove(1); // Further testing of remove method: make sure that false is returned. Use debugger.
return 0;
}
/* After having checked and executed the code, modify the following function
void printSet(Set s);
to have a reference type parameter:
void printSet(Set &s);
Remember to do it twice: in the implementation (.cpp) and in the prototype (header).
*/
Also don't mind the comments this is for school.