Help with using a class in C++

Hello, I"m new here and trying to do well in a class I am taking. I just finished writing code for an assignment I have due and am looking for guidance. The assignment is simple on the surface. I am given the following header file:

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
#ifndef INTBOX_H
#define INTBOX_H

#include <iostream>


/* _________________
  /                 \
  |  IntBox  Class  |
  \_________________/
   
    Purpose: Implements an Integer Box, as required by the Emperor Lrrr

    An Integer-Box is a class that encapsulates an array of Integers
    The size of the array is specified at declaration.

*/

// ---------------  Class IntBox Declarations
class IntBox
{ 
public:  
  int* m_ints = NULL;                 // Array of Integers
  int m_boxsize;                      // number of Integers in this box       


public:
  // Purpose: Constructs an Integer Box
  // Preconditions:
  //     's' is greater than 0;
  // Postconditions: 
  //     m_ints points to a dynamically allocated array of size 's'
  //     all elements of m_ints[] are initiallized to 'a'.
  
  IntBox(int s, int a);


  /* 
   * --------- Big 3 Member Functions -----------
   */

  // Purpose: Destructor
  // Postconditions: m_ints[] deallocated
  ~IntBox();

  // Purpose: Operator=, performs a deep copy of 'rhs' into 'this' IntBox
  // Parameters: rhs, IntBox to be copied
  // Returns: *this
  // Postconditions: *this == rhs
  const IntBox& operator=(const IntBox& rhs);

  // Purpose: Copy Constructor
  // Parameters: rhs - IntBox to be copied
  // Postconditions:  *this == rhs
  IntBox(const IntBox& rhs);


  /* 
   * ----- Simple Accessor Operations ----- 
   */

  // Purpose: Sets a value in the IntBox
  // Parameters: 'i' location to set
  //             'x' value to store
  // PreConditions: 'i' is between the boundaries of the IntBox 
  // Postconditions:  element 'i' in the IntBox is set to 'x'
	void set( int i, int x);


  /* 
   * ----- Complex Accessor Operations ----- 
   */
  
  // Purpose: prints the IntBox
  friend std::ostream& operator<< (std::ostream& out, 
                                   const IntBox& box);
}; // IntBox

#endif 


And I must create an Implementation file that uses every function in this class. So far this is what I have coded:

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
#include <iostream>
#include "IntBox.h"

using namespace std;
//using std::cout;
//using std::cin;

IntBox::IntBox(int s, int a)
{
	if (s > 0)
	{
		s = m_boxsize;
		m_ints = new int[s];
		for (int i = 0; i < s; i++)
		{
			m_ints[i] = a;
		}
	}
	else
	{
		cout<<"Array size must be greater than 0!!!"<<endl;
	}
}

IntBox::~IntBox()
{
	delete [] m_ints;
}

const IntBox & IntBox::operator=(const IntBox& rhs)
{
	if(this != &rhs)
		*m_ints = *rhs.m_ints;
	return *this;
}

IntBox::IntBox(const IntBox& rhs)
{
	m_ints = new int;
	*this = rhs;
}

void IntBox::set( int i, int x)
{
	if (i > 0 && i < m_boxsize)
		m_ints[i] = x;
	else
		cout<<"Out of parameters!!!!"<<endl;
}

std::ostream& operator<< (std::ostream& out, const IntBox& box)
{
	cout<<IntBox.m_ints<<endl;
}


My understanding of this is vague, but I can't get the last function to compile. Part of my problem is I am completely lost by the syntax used in the last function to print out an array as this is a new concept for me (hence the assignment I suppose) and I've been doing trial and error to see how I am suppose to print out an array using that syntax. I've had no luck, so what is at the bottom of my implementation file is where I've left off.

This of course does not compile. with the code as it is above, I get one error stating the following:

intbox.cpp:55 error: expected primary-expression before '.' token
cout<<INtbox.m_ints<<endl;

which tells me that I'm using my member relations wrong and I'm running out of ideas for the night.

Can anyone provide some guidance on what exactly the last section of my header is doing or how I should be using it? I really appreciate it, and if I am abusing site rules or in the wrong section, please let me know. I'm not looking to have someone code it for me, I'm just using another resource to learn what I'm doing.
A few things:

As to your error, you are giving it a data type for the '.' operator, rather than the box parameter you are passing to the function. Also, rather than using the ostream object you are passing, you are giving it to cout instead, which isn't generally what you want. You also aren't returning anything. So, it should look like this:
1
2
3
4
5
6
7
8
9
10
11
std::ostream& operator<< (std::ostream& out, const IntBox& box) {
    // we are printing an array here, I'll make it look pretty
    out << '[';
    out << box.m_ints[0];
    for (int i = 1; i < box.m_boxsize; ++i)
        out << ", " << box.m_ints[i];
    out << ']';

    // return the ostream object so we can chain
    return out;
}


You also have a few other problems with your implementation file. You have line 12 backwards, your copy assignment operator doesn't copy the array size or any array object element apart from the first one, your copy constructor doesn't allocate an array, only a single variable. That should give you something to work on!
NT3, thank you so much for your guidance. I'm able to print my array and it appears the only functions that are failing are the two you mentioned: My Operator= and Copy Constructor.

Here's my updated code with a few things I was playing around with commented out

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
#include <iostream>
#include "IntBox.h"

using namespace std;
//using std::cout;
//using std::cin;

IntBox::IntBox(int s, int a)
{
	if (s > 0)
	{
		m_boxsize = s;
		m_ints = new int[s];
		for (int i = 0; i < s; i++)
		{
			m_ints[i] = a;
		}
	}
	else
	{
		cout<<"Array size must be greater than 0!!!"<<endl;
	}
}

IntBox::~IntBox()
{
	delete [] m_ints;
}

const IntBox & IntBox::operator=(const IntBox& rhs)
{
	if(this != &rhs)
	{
		for (int i = 0; i < m_boxsize; i++)
		{
			m_ints[i] = *rhs.m_ints;
		}
	}
	else
		cout<<"Not Valid!!! (Arguments are equal)"<<endl;
//	*m_ints = *rhs.m_ints;
	return *this;
}

IntBox::IntBox(const IntBox& rhs)
{
/*	for (int i = 0; i < m_boxsize; i++)
	{
		m_ints[i] = new int;
		*this = rhs;
	}
*/	
	m_ints = new int;
	*this = rhs;
}

void IntBox::set( int i, int x)
{
	if (i > 0 && i <= m_boxsize)
		m_ints[i] = x;
	else
		cout<<"Out of parameters!!!!"<<endl;
}

std::ostream& operator<< (std::ostream& out, const IntBox& box)
{
	out << "[";
	out << box.m_ints[0];
	for (int i = 1; i < box.m_boxsize; i++)
		out << ", " << box.m_ints[i];
	out << ", ]";

	return out;
}


I believe my problems consist of the following:

1. Understanding how to copy the array size properly in the Operator= function. I tried Googling it, but maybe I was typing the wrong search words?

2. How to properly allocate an array in the Copy Constructor. When I have the code I commented out implemented, I get an error stating the following:

" error: invalid conversion from 'int*' to 'int' [-fpermissive]
m_ints[i] = new int;
^ "

(the carrot displays below the = sign, but for some reason I couldn't format it to show there in this post...)

Can any context/guidance be given here?

I know I'm very close. I was given a tester.cpp file that will use all of the functions and what output it should give. This is what my output is suppose to look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
IntBox Tester
#1
[ 2, 2, 2, 2, 2, 2, ]
#2
[ 2, 2, 2, 2, ]
#3
[ 5, 77, 5, 5, 5, ]
#4
[ 8, 8, 1, 8, 8, 8, 8, 8, ]
#5 : Operator=
[ 8, 8, 1, 8, 8, 8, 8, 8, ]
[ 8, 8, 1, 8, 8, 8, 8, 8, ]
[ 8, 8, 1, 8, 8, 8, 8, 8, ]
[ 8, 8, 1, 8, 8, 42, 8, 8, ]
#6 : Copy Constructor
[ 2, 2, 2, 2, 2, 2, ]
[ 2, 2, 2, 2, 2, 2, ]
[ 2, 2, 2, 2, 2, 2, ]
[ 2, 2, 2, 88, 2, 2, ]


However, my output as the code is above looks like this:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
IntBox Tester
#1
[ 2, 2, 2, 2, 2, 2, ]
#2
[ 2, 2, 2, 2, ]
#3
[ 5, 77, 5, 5, 5, ]
#4
[ 8, 8, 1, 8, 8, 8, 8, 8, ]
#5 : Operator=
[ 8, 8, 1, 8, 8, 8, 8, 8, ]
[ 8, 8, 8, 8, 8, ]
[ 8, 8, 1, 8, 8, 8, 8, 8, ]
[ 8, 8, 8, 8, 8, ]
#6 : Copy Constructor
Segmentation fault (core dumped)


I think I'm just not grasping the concept of Constructors with classes that is being taught, any and all insight is greatly appreciated.

*NOTE*

I figured including the tester.cpp file that was given to me might help understand the printout, so I added it below:

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
#include <iostream>
#include "IntBox.h"

using namespace std;

int main () 
{
	cout << "IntBox Tester" << endl;
	
	cout << "#1" << endl;
	IntBox a(6,2);
	cout << a << endl;

	cout << "#2" << endl;
	IntBox b(4,2);
	cout << b << endl;
	
	cout << "#3" << endl;
	IntBox c(5,5);
	c.set( 1, 77 );
	cout << c << endl;
	
	cout << "#4" << endl;
	IntBox d(8,8);
	d.set( 2, 1 );
	cout << d << endl;

	cout << "#5 : Operator=" << endl;
	c = d;
	cout << d << endl;
	cout << c << endl;
	c.set( 5, 42 );
	cout << d << endl;
	cout << c << endl;
	
	cout << "#6 : Copy Constructor" << endl;
	IntBox e(a);
	cout << a << endl;
	cout << e << endl;
	e.set( 3, 88 );
	cout << a << endl;
	cout << e << endl;

  
  return 0;
}
Just to be clear, let's define exactly what the copy constructor and copy assignment operator need to do. I'll assume you know exactly how they're evoked. Your tester.cpp gives a good demonstration.

Copy constructor
Copy all member variables from another object.
Deep copy any pointer members (copy the data they point to, not the pointer itself).

Copy assignment operator
Everything the copy constructor does, except we must remember that this object is already instantiated and memory has been allocated, so this memory should be cleared up first.

Here's a little example that might help clarify things.

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
#include <iostream>

class Array {
public:
	Array(int size) : m_iSize(size) {
		std::cout << "In constructor Array(int)\n";
		
		m_pNums = new int[size];
	}
	
	Array(const Array& rhs) {
		std::cout << "In copy constructor Array(const Array&)\n";
		
		// Allocate enough space to copy data from rhs
		m_pNums = new int[rhs.m_iSize];
		
		// Deep copy m_pNums
		for (int i = 0; i < rhs.m_iSize; i++)
			m_pNums = rhs.m_pNums;
			
		// Copy other member(s) normally
		m_iSize = rhs.m_iSize;
	}
	
	~Array() {
		std::cout << "In destructor ~Array()\n";
		
		delete []m_pNums;
	}
	
	
	const Array& operator=(const Array& rhs) {
		std::cout << "In assignment operator\n";
	
		if (this == &rhs)
			return *this;
		
		// Since this object has been instantiated, m_pNums must
		// already be allocated, so clear it up first
		delete []m_pNums;
		
		// From now it's the same process as the copy constructor
		
		m_pNums = new int[rhs.m_iSize];
		
		for (int i = 0; i < rhs.m_iSize; i++)
			m_pNums = rhs.m_pNums;
			
		m_iSize = rhs.m_iSize;		

		return *this;
	}
	
private:
	int* m_pNums;
	int m_iSize;
};

int main() {
	Array a(20);	// Regular constructor
	Array b = a;	// Copy constructor	
	a = b;			// Copy assignment operator
}


Also, maybe this isn't the right place for this since it is an assignment for a class and all, but it's worth noting that managing memory this way and using naked pointers is very prone to errors and is pretty much totally superseded. Nowadays there are much better options, like smart pointers (e.g. std::unique_ptr). Just something for you to think about, that's all.
Last edited on
denormal, thank you so much for that example!!! I understood a little better looking at your example code and was able to make sure there was no memory leaks (which was the biggest part to accomplish outside of understanding syntax)

I truly appreciate it. I've finished my program and I'm quite proud. In reference to your comment, is there a better place to ask about things like this? I remember when I'd google things like this, it'd take me to the forums and after looking at a few post back then it seems other users do it on this site. I did browse a bit and briefly read the rules. I didn't want to come off as trying to ask anyone to "code for me" as opposed to help me understand "what to code" or "how to code" a part of my program.

Should I be inquiring about things like this elsewhere?

(again, thank you so much demoral and NT3)

EDIT: Looking again, is it best to have put this in the Beginner's section? I took that to mean programming, but not specific to any language.. If so I'll be sure to post there if I get stuck while writing a program again.
Last edited on
By denormal's "last comment", do you mean his last paragraph? I think you've misunderstood what he meant by "this isn't the right place for this" - what he means is he was suggesting a better way of doing your code, but you probably wouldn't use it because that would defeat the purpose of the assignment.

Basically, I would suggest maybe next time this could go in the Beginner's forum - I tend to prefer to assume "General Programming" as "Advanced Programming". Of course, it doesn't really matter, just the people who'll answer this kind of question are more likely to look on the Beginner's forum. At least you've taken the time to read the rules and try to follow them - its really annoying when people don't.
Topic archived. No new replies allowed.