Saving an class with a private constructor

Hello, I have a problem with this code that is supposed to behave "like a STL set". It's part of a school assignment. When I'm saving integers or strings, it works. But when I try to save an class with a private default constructor (the school testing system uses this to validate if the points in the assignment are being kept, classes being saved to the "set" have guaranteed working copy constructor, operator < for comparing and operator = for assigning). Is there a way to save the class without calling the default constructor or is this whole code just incorrect? Any kind of help will be much appreciated.

Here is the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  template <class T>
class CSet
{
private:

    struct Node
    {
        T m_Data{}; // need to save class with a private constructor
        Node *m_Next{};
    };

    Node * m_Node;
    unsigned int m_Size;

public:

    // default constructor
    CSet () : m_Node(nullptr), m_Size(0) {}
    
    // copy constructor
    CSet (CSet const &in) : m_Size(0) {
        Node * current = in.m_Node;
        for (unsigned int i = 0; i < in.m_Size; i++) {
            Insert(current->m_Data);
            current = current->m_Next;
        }
    }
    
    // operator=
    CSet & operator = (CSet const &in) {
        if (this == &in) {
            return *this;
        }
        m_Size = 0;

        for (unsigned int i = 0; i < m_Size; i++) {
            Node * next = m_Node->m_Next;
            delete m_Node;
            m_Node = next;
        }
        m_Node = nullptr;

        Node * current = in.m_Node;
        for (unsigned int i = 0; i < in.m_Size; i++) {
            Insert(current->m_Data);
            current = current->m_Next;
        }
        return *this;
    }
    
    // destructor
    ~CSet() {
        Node * current = m_Node;
        for (unsigned int i = 0; i < m_Size; i++) {
            Node * next = current->m_Next;
            delete current;
            current = next;
        }
        m_Node = nullptr;
    }
    
    // Insert
    bool Insert (T in) {
        if (m_Size == 0) {
            m_Node = new Node; // problem here
            m_Node->m_Data = in;
            m_Node->m_Next = nullptr;
            m_Size = 1;
            return true;
        }

        Node * current = m_Node;
        Node * prev = nullptr;

        for (unsigned int i = 0; i < m_Size; i++) {
            if (!(current->m_Data < in || in < current->m_Data)) {
                return false;
            }
            prev = current;
            current = current->m_Next;
        }

        Node * newNode = new Node; // and another here
        current->m_Data = in;
        current->m_Next = nullptr;

        if (prev) {
            prev->m_Next = newNode;
        }
        m_Size++;
        return true;
    }
    
    // Remove
    bool Remove (T in) {
        Node * prev = nullptr;
        Node * current = m_Node;
        while (current && (current->m_Data < in || in < current->m_Data)) {
            prev = current;
            current = current->m_Next;
        }
        if (!current) return false;
        if (prev) {
            prev->m_Next = current->m_Next;
        }
        else {
            m_Node = current->m_Next;
        }

        delete current;
        m_Size--;
        return true;
    }
    
    // Contains
    bool Contains (T in) const {
        Node * current = m_Node;

        for (unsigned int i = 0; i < m_Size; i++) {
            if (!(current->m_Data < in || in < current->m_Data)) {
                return true;
            }
            current = current->m_Next;
        }
        return false;
    }
    
    // Size
    unsigned int Size () const {
        return m_Size;
    }
};
Does the class have a public non-default constructor - or can one be provied? Can lines 83-85 just be:

 
Node * newNode = new Node(in);

The thing is that I don't know what will be supplied as T. Type that is passed to the functions is described only as:

Class Type, template parameter, guarantees the following functionality:
• copy constructor,
• copy assignment operator,
• operator< for comparing two elements.

as in Contains(Type).
What about something like (NOT tried):

1
2
3
4
5
6
7
8
9
10
struct Node
    {
        T m_Data{}; // need to save class with a private constructor
        Node *m_Next{};
        Node(const T& md) : m_data(md) {}
    };

...

Node *newNode = new Node(in);


Note that for Insert(), Remove() and Contains, T should be passed by const ref and not by value.
Last edited on
Thanks, it works, but now it leaves uncleared memory. Any ideas where it might occur?
Last edited on
I've quickly re-factored the code. Try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <utility>
#include <iostream>

template <class T>
class CSet
{
private:
	struct Node {
		T m_Data {};
		Node* m_Next {};

		Node(const T& md) : m_Data(md) {}
	};

	Node* m_Node {};	// Top
	size_t m_Size {};

public:
	// default constructor
	CSet() {}

	// copy constructor
	CSet(CSet const& in) : m_Size(in.m_Size) {
		for (Node* incur = in.m_Node, *prev = m_Node; incur; incur = incur->m_Next) {
			const auto newmd {new Node(incur->m_Data)};

			if (prev != nullptr)
				prev->m_Next = newmd;

			if (m_Node == nullptr)
				m_Node = newmd;

			prev = newmd;
		}
	}

	CSet& swap(CSet& cs) {
		std::swap(cs.m_Node, m_Node);
		std::swap(cs.m_Size, m_Size);

		return *this;
	}

	// operator=
	CSet& operator=(CSet in) {
		swap(in);

		return *this;
	}

	// destructor
	~CSet() {
		while (m_Node) {
			const auto next{m_Node->m_Next};

			delete m_Node;
			m_Node = next;
		}
	}

	// Insert
	bool Insert(const T& in) {
		Node* prev {};

		for (auto current = m_Node; current; prev = current, current = current->m_Next)
			if (!(current->m_Data < in || in < current->m_Data))
				return false;

		const auto newNode {new Node(in)};

		if (prev)
			prev->m_Next = newNode;

		if (m_Node == nullptr)
			m_Node = newNode;

		++m_Size;
		return true;
	}

	// Remove
	bool Remove(T in) {
		Node* prev {};
		Node* current {m_Node};

		for (; current && (current->m_Data < in || in < current->m_Data); prev = current, current = current->m_Next);

		if (!current)
			return false;

		if (prev)
			prev->m_Next = current->m_Next;
		else
			m_Node = current->m_Next;

		delete current;
		--m_Size;
		return true;
	}

	// Contains
	bool Contains(const T& in) const {
		for (auto cur = m_Node; cur; cur = cur->m_Next)
			if (!(cur->m_Data < in || in < cur->m_Data))
				return true;

		return false;
	}

	// Size
	size_t Size() const {
		return m_Size;
	}

	void display() const {
		for (auto cur = m_Node; cur; cur = cur->m_Next)
			std::cout << cur->m_Data << ' ';

		std::cout << '\n';
	}
};

int main()
{
	CSet<int> cs, cs2;

	cs.Insert(1);
	cs.Insert(2);
	cs.Insert(3);
	cs.Insert(2);

	cs.display();

	auto cs1(cs);

	cs1.display();

	cs2 = cs;
	cs2.display();

	cs2.Remove(3);
	cs2.display();
}

Thanks, great code! Works at 100%.
Topic archived. No new replies allowed.