Printing more than once

Why does motto3 print twice (line 91)? See output.

Constructor called.
Constructor called.
Constructor called.
Executing: motto3 = motto1 + motto2
Add operator function called.
Constructor called.
Copy constructor called.
Destructor called.
Assignment operator function called.
Destructor called.
Done!!

Executing: motto3 = motto3 + motto1 + motto2
Add operator function called.
Constructor called.
Copy constructor called.
Destructor called.
Add operator function called.
Constructor called.
Copy constructor called.
Destructor called.
Assignment operator function called.
Destructor called.
Destructor called.
Done!!

motto3 contains:
The devil takes care of his own. If you sup with the devil use a long spoon.
The devil takes care of his own. If you sup with the devil use a long spoon.

Destructor called.
Destructor called.
Destructor called.
Press any key to continue . . .
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
// Ex8_07.cpp
// How many copy operations?
#include <iostream>
#include <cstring>
using std::cout;
using std::endl;

class CMessage
{
private:
  char* m_pMessage;                                        // Pointer to object text string

public:
  // Function to display a message
  void showIt() const
  {
    cout << m_pMessage << endl;
  }

  // Overloaded addition operator
  CMessage operator+(const CMessage& aMess) const
  {
    cout << "Add operator function called." << endl;
    size_t len{ strlen(m_pMessage) + strlen(aMess.m_pMessage) + 1 };
    CMessage message;
    message.m_pMessage = new char[len];
    strcpy_s(message.m_pMessage, len, m_pMessage);
    strcat_s(message.m_pMessage, len, aMess.m_pMessage);
    return message;
  }

  // Overloaded assignment operator for CMessage objects
  CMessage& operator=(const CMessage& aMess)
  {
    cout << "Assignment operator function called." << endl;
    if (this != &aMess)                                    // Check addresses are not equal
    {
      // Release memory for 1st operand
      delete[] m_pMessage;
      size_t length{ strlen(aMess.m_pMessage) + 1 };
      m_pMessage = new char[length];

      // Copy 2nd operand string to 1st
      strcpy_s(this->m_pMessage, length, aMess.m_pMessage);

    }
    return *this;                                          // Return a reference to 1st operand
  }

  // Constructor definition
  CMessage(const char* text = "Default message")
  {
    cout << "Constructor called." << endl;
    size_t length{ strlen(text) + 1 };
    m_pMessage = new char[length];                         // Allocate space for text
    strcpy_s(m_pMessage, length, text);                    // Copy text to new memory
  }

  // Copy constructor definition
  CMessage(const CMessage& aMess)
  {
    cout << "Copy constructor called." << endl;
    size_t length{ strlen(aMess.m_pMessage) + 1 };
    m_pMessage = new char[length];
    strcpy_s(m_pMessage, length, aMess.m_pMessage);
  }

  // Destructor to free memory allocated by new
  ~CMessage()
  {
    cout << "Destructor called." << endl;                  // Just to track what happens
    delete[] m_pMessage;                                   // Free memory assigned to pointer
  }
};

int main()
{
	{
		CMessage motto1 {"The devil takes care of his own. "};
		CMessage motto2 {"If you sup with the devil use a long spoon.\n"};
		CMessage motto3;
		cout << " Executing: motto3 = motto1 + motto2 " << endl;
		motto3 = motto1 + motto2;
		cout << " Done!! " << endl << endl;

		cout << " Executing: motto3 = motto3 + motto1 + motto2 " << endl;
		motto3 = motto3 + motto1 + motto2;
		cout << " Done!! " << endl << endl;

		cout << "motto3 contains:" << endl;
		motto3.showIt();
	}

  system("pause");
  return 0;
}
You've not implemented all the necessary default methods, plus you have a memory leak as I've indicated below.
1
2
3
4
5
6
7
8
9
10
11
  // Overloaded addition operator
  CMessage operator+(const CMessage& aMess) const
  {
    cout << "Add operator function called." << endl;
    size_t len{ strlen(m_pMessage) + strlen(aMess.m_pMessage) + 1 };
    CMessage message;  // this allocates m_pMessage and copies in "Default message"
    message.m_pMessage = new char[len];  // you're overwriting the pointer, loosing the original message
    strcpy_s(message.m_pMessage, len, m_pMessage);
    strcat_s(message.m_pMessage, len, aMess.m_pMessage);
    return message;  // You don't have a copy or move, but you do have a destructor that releases memory--could get messy
  }
closed account (E0p9LyTq)
Why does motto3 print twice (line 91)?

Look at what lines 83 and 87 are doing.

It isn't printing twice, you are assigning a value (motto1 + motto2) and then adding it again (motto3 + motto1 + motto2).
Last edited on
kbw,

I stepped through the program, and the CMessage message; does not allocate m_pMessage and does not copy in the "Default message". message is essentially an uninitialized object. I suspect it may be because it is a rhs object instead of a lhs object.

FurryGuy,

Why wasn't line 83 overwritten by line 87? Are there two copies of motto3?



I stepped through the program, and the CMessage message; does not allocate m_pMessage and does not copy in the "Default message". message is essentially an uninitialized object.
 
CMessage motto3;
This calls the default constructor, which in your case is:
1
2
3
4
5
6
7
  CMessage(const char* text = "Default message")
  {
    cout << "Constructor called." << endl;
    size_t length{ strlen(text) + 1 };
    m_pMessage = new char[length];                         // Allocate space for text
    strcpy_s(m_pMessage, length, text);                    // Copy text to new memory
  }


Why does motto3 print twice (line 91)? See output.
It doesn't. motto3="The devil takes care of his own. If you sup with the devil use a long spoon.\nThe devil takes care of his own. If you sup with the devil use a long spoon.\n"
Last edited on
Ah yes! Thank you, kbw.
Topic archived. No new replies allowed.