Copy Constructor Error keeps Occurring

Hello all,

I am programming in Visual Studio 2008 and keep getting an error when I try to add a copy constructor in, just seeing if anyone can help me solve the problem.

#include <iostream>
#include <vector>

using namespace std;

class Text
{
public:
float Top; //The distance from the top of the page in inches
float Left; //Left margin from where the text starts
float Right; //Right margin from where the text ends
int fontType; //The type of font
int fontSize; //The size of the font
int noChars; //The number of Characters
Text(); //Empty Constructor
Text(Text& txt);
~Text(); //Destructor
Text(float Top, float Left, float Right, int fontType, int fontSize, int noChars); //Constructor with parameters
void operator = (Text& txt);
void display(); //Displays the field values
};
//======================================================================================================
Text::Text()
{
// initialize the values for the fields of Text
Top = 0.0;
Left = 0.0;
Right = 0.0;
fontType = 1;
fontSize = 12;
noChars = 0;
}
//------------------------------------------------------------------------------------------------------
Text::Text(float Top, float Left, float Right, int fontType, int fontSize, int noChars)
{
//initalize the variables to their respectable parameters
this->Top = Top;
this->Left = Left;
this->Right = Right;
this->fontType = fontType;
this->fontSize = fontSize;
this->noChars = noChars;
}
//------------------------------------------------------------------------------------------------------
Text::~Text()
{

}
//------------------------------------------------------------------------------------------------------
Text::Text(Text& txt)
{
Top = txt.Top;
Left = txt.Left;
Right = txt.Right;
fontType = txt.fontType;
fontSize = txt.fontSize;
noChars = txt.noChars;
}
//---------------------------------------------------------------------------------------
void Text::operator =(Text& txt)
{
Top = txt.Top;
Left = txt.Left;
Right = txt.Right;
fontType = txt.fontType;
fontSize = txt.fontSize;
noChars = txt.noChars;
}
//----------------------------------------------------------------------------------------
void Text::display()
{
cout << "Text: \n \n" << "Top: " << Top << "\n" << "Left: " << Left << "\n" <<
"Right: " << Right << "\n" << "Font Type: " << fontType << "\n" <<
"Font Size: " << fontSize << "\n" << "Number of Characters: " << noChars << "\n \n" << endl;
}
//------------------------------------------------------------------------------------------------------
ostream& operator<< (ostream& s, Text& txt)
{
s << "Text: \n \n" << "Top: " << txt.Top << "\n" << "Left: " << txt.Left << "\n" <<
"Right: " << txt.Right << "\n" << "Font Type: " << txt.fontType << "\n" <<
"Font Size: " << txt.fontSize << "\n" << "Number of Characters: " << txt.noChars << "\n \n" << endl;
return s;
}


The error I keep on getting is
c:\program files\microsoft visual studio 9.0\vc\include\vector(1209) : error C2558: class 'Text' : no copy constructor available or copy constructor is declared 'explicit'

This is where it is going to get displayed, so maybe it has something to do with it

class Document
{
public:
vector<Text> aTexts; //A vector of Text class objects
vector<Table> aTables; //A vector of Table class objects
vector<Graphics> aGraphics; //A vector of Graphics class objects
void addElement(Text v);
void addElement(Table v);
void addElement(Graphics v);
Document(); //empty constructor
~Document(); // destructor
void display();
friend ostream& operator<< (ostream& s, Document& d);
};
//======================================================================================================
Document::Document()
{
// do nothing because the variables have already been initialized
}
//------------------------------------------------------------------------------------------------------
Document::~Document()
{
// do nothing - compiler default
}
//------------------------------------------------------------------------------------------------------
void Document::addElement(Text v)
{
// adds the Text object x to the end of the Text vector
aTexts.push_back(v);
}
//------------------------------------------------------------------------------------------------------
void Document::addElement(Table v)
{
// adds the Table object x to the end of the Table vector
aTables.push_back(v);
}
//------------------------------------------------------------------------------------------------------
void Document::addElement(Graphics v)
{
// adds the Graphics object to the end of the Graphics vector
aGraphics.push_back(v);
}
//------------------------------------------------------------------------------------------------------
void Document::display()
{
for (int i = 0; i < aTexts.size(); i++)
{
cout << aTexts[i] << endl;
}

for (int i = 0; i < aTables.size(); i++)
{
cout << aTables[i] << endl;
}

for (int i = 0; i < aGraphics.size(); i++)
{
cout << aGraphics[i] << endl;
}
}
//------------------------------------------------------------------------------------------------------
ostream& operator<< (ostream& s, Document& d)
{
for(int i = 0; i < d.aTexts.size(); i++)
{
s << d.aTexts[i];
}

for(int i = 0; i < d.aTables.size(); i++)
{
s << d.aTables[i];
}

for(int i = 0; i < d.aGraphics.size(); i++)
{
s << d.aGraphics[i];
}

return s;
}

any help would be greatly appreciated
The constructor Text(Text& txt); should be Text(const Text& txt);

In other words copy constructors should use constant references
I had it like that but I was still getting an error
I would take a good hard look at the assignment operator, as well.
the member function(void Text::operator = (Text& txt))should also use constant references.
eg.
void operator=(const Text& txt);
Just to be precise, the copy constructor of an object O is defined as a constructor which takes exactly one parameter -- an instance of O by const reference.

1
2
3
4
5
class Foo {
  public:
      Foo( const Foo& ); // This is a copy constructor
      Foo( Foo& ); // This is NOT.
};


Ya I should have left that part in when I posted this, but even when I put the const in it still gives me an error when i try to compile it, just wasnt sure if there was something weird with it when it goes to the vector or if something else is going on
Here is your code again:
Notice that I have added the const keyword to the copy
constructor and assignment operator= functions.
Notice also that I have commented out the parts which uses Table and the Graphics class, as you have not given their code.

This program runs on MSVC 2008, so it is possible that you have the
same problems with Table and Graphics class:

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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <iostream>
#include <vector>
  
  using namespace std;

  class Text
  {
  public:
    float Top; //The distance from the top of the page in inches
    float Left; //Left margin from where the text starts
    float Right; //Right margin from where the text ends
    int fontType; //The type of font
    int fontSize; //The size of the font
    int noChars; //The number of Characters
    Text(); //Empty Constructor
    Text(const Text& txt);
    ~Text(); //Destructor
    Text(float Top, float Left, float Right, int fontType, int fontSize, int noChars); //Constructor with parameters
    void operator = (const Text& txt);
    void display(); //Displays the field values
  };
  //======================================================================================================
  Text::Text()
  {
    // initialize the values for the fields of Text
    Top = 0.0;
    Left = 0.0;
    Right = 0.0;
    fontType = 1;
    fontSize = 12;
    noChars = 0;
  }
  //------------------------------------------------------------------------------------------------------
  Text::Text(float Top, float Left, float Right, int fontType, int fontSize, int noChars)
  {
    //initalize the variables to their respectable parameters
    this->Top = Top;
    this->Left = Left;
    this->Right = Right;
    this->fontType = fontType;
    this->fontSize = fontSize;
    this->noChars = noChars;
  }
  //------------------------------------------------------------------------------------------------------
  Text::~Text()
  {

  }
  //------------------------------------------------------------------------------------------------------
  Text::Text(const Text& txt)
  {
    Top = txt.Top;
    Left = txt.Left;
    Right = txt.Right;
    fontType = txt.fontType;
    fontSize = txt.fontSize;
    noChars = txt.noChars;
  }
  //---------------------------------------------------------------------------------------
  void Text::operator =(const Text& txt)
  {
    Top = txt.Top;
    Left = txt.Left;
    Right = txt.Right;
    fontType = txt.fontType;
    fontSize = txt.fontSize;
    noChars = txt.noChars;
  }
  //----------------------------------------------------------------------------------------
  void Text::display()
  {
    cout << "Text: \n \n" << "Top: " << Top << "\n" << "Left: " << Left << "\n" << 
      "Right: " << Right << "\n" << "Font Type: " << fontType << "\n" << 
      "Font Size: " << fontSize << "\n" << "Number of Characters: " << noChars << "\n \n" << endl;
  }
  //------------------------------------------------------------------------------------------------------
  ostream& operator<< (ostream& s, Text& txt)
  {
    s << "Text: \n \n" << "Top: " << txt.Top << "\n" << "Left: " << txt.Left << "\n" << 
      "Right: " << txt.Right << "\n" << "Font Type: " << txt.fontType << "\n" << 
      "Font Size: " << txt.fontSize << "\n" << "Number of Characters: " << txt.noChars << "\n \n" << endl;
    return s;
  }



  class Document
  {
  public:
    vector<Text> aTexts; //A vector of Text class objects
    //vector<Table> aTables; //A vector of Table class objects
    //vector<Graphics> aGraphics; //A vector of Graphics class objects
    void addElement(Text v);
    //void addElement(Table v);
    //void addElement(Graphics v);
    Document(); //empty constructor
    ~Document(); // destructor
    void display();
    friend ostream& operator<< (ostream& s, Document& d);
  };
  //======================================================================================================
  Document::Document()
  {
    // do nothing because the variables have already been initialized
  }
  //------------------------------------------------------------------------------------------------------
  Document::~Document()
  {
    // do nothing - compiler default
  }
  //------------------------------------------------------------------------------------------------------
  void Document::addElement(Text v)
  {
    // adds the Text object x to the end of the Text vector
    aTexts.push_back(v);
  }
  //------------------------------------------------------------------------------------------------------
  /*void Document::addElement(Table v)
  {
    // adds the Table object x to the end of the Table vector
    aTables.push_back(v);
  }*/
  //------------------------------------------------------------------------------------------------------
  /*void Document::addElement(Graphics v)
  {
    // adds the Graphics object to the end of the Graphics vector
    aGraphics.push_back(v);
  }*/
  //------------------------------------------------------------------------------------------------------
  void Document::display()
  {
    for (int i = 0; i < aTexts.size(); i++)
    {
      cout << aTexts[i] << endl;
    }

    /*for (int i = 0; i < aTables.size(); i++)
    {
      cout << aTables[i] << endl;
    }*/

    /*for (int i = 0; i < aGraphics.size(); i++)
    {
      cout << aGraphics[i] << endl;
    }*/
  }
  //------------------------------------------------------------------------------------------------------
  ostream& operator<< (ostream& s, Document& d)
  {
    for(int i = 0; i < d.aTexts.size(); i++)
    {
      s << d.aTexts[i];
    }

    /*for(int i = 0; i < d.aTables.size(); i++)
    {
      s << d.aTables[i];
    }*/

    /*for(int i = 0; i < d.aGraphics.size(); i++)
    {
      s << d.aGraphics[i];
    }*/

    return s;
  }



//TESTING  TESTING--------------------------------------------------
  int main()
  {

    Text myText_1 (1.0, 2.0, 3.0, 1,1, 23);
    Document myDocObj;

    myDocObj.addElement(myText_1);

    myDocObj.display();

    return 0;
  
  }
A few comments.
1. The signature of your assignment operator is incorrect. It should not return void.

2. There are a number of class member functions that the compiler will generate for you. You should understand why this is the case and what they do.

3. Your ostream operators should take a const reference to your object.

4. void Document::addElement(Text v) should probably take a reference parameter rather than a value. This will generate an unneeded copy.

Topic archived. No new replies allowed.