I want to have a copy of the currently running instance.
When i change a 开发者_如何学Pythonvalue in the copy, original object is also affected. The copy acts as an instance.
How to avoid this? I need to create an independent copy of the calling object.
Set operator+(Set s){
Set temp = *this;
for(int i=0; s.elements[i] != '\0'; i++){
temp(s.elements[i]);
}
temp.elements[0] = 'X'; // <- this affects calling object also :(
return temp;
}
The problem is that Set temp = *this;
makes a shallow copy, not a deep copy. You will have to modify the copy constructor and assignment operators for the Set
class so that they make copies of all the member/contained objects.
E.g:
class Set
{
public:
Set()
{
elements = new SomeOtherObject[12];
// Could make elements a std::vector<SomeOtherObject>, instead
}
Set(const Set& other)
{
AssignFrom(other);
}
Set& operator=(const Set& other)
{
AssignFrom(other);
return *this;
}
private:
void AssignFrom(const Set& other)
{
// Make copies of entire array here, as deep as you need to.
// You could simply do a top-level deep copy, if you control all the
// other objects, and make them do top-level deep copies, as well
}
SomeOtherObject* elements;
};
Not that your function already makes two copies, since it takes its argument and returns its result per copy:
Set operator+(Set s);
So you wouldn't have to copy s
, because it's already copied. I suppose this is involuntarily, so you might want to read about how to pass objects to functions and how to return objects from function in C++.
The problem you're reporting, though, hints at your copy constructor not working properly. Did you implement the copy constructor or are you using the compiler-supplied one?
This probably depends on how Set
is implemented. If the assignment operator and the copy constructor haven't been overloaded to do a deep copy(including elements
) then it won't work as expected.
Have you implemented a copy constructor for your class? Default copy constructor will copy any pointer in your class, but not the content you are pointing to. You need to create a copy constructor or overload the '=' operator.
I would avoid a char pointer completely and use std::string instead. This way you dont even need a copy constructor and an assigment operator because the compiler generated once will do just fine. (because 'elements' of the 'Set' class is copy-constructible and has an assignment operator) Here is my solution:
#include <iostream>
#include <string>
class Set{
std::string elements;
public:
Set() {
elements = "";
}
explicit Set(char* _elements) {
if (_elements)
elements = _elements;
}
Set operator+(const Set& s){
Set temp(*this);
temp.elements += s.elements;
return temp;
}
};
Btw. I added a constructor from char* so that 'elements' can somehow be initialized from outside. Not sure if this is what you wanted.
Ok. I went through rule of three and did the following changes... Can you point out what's wrong with this?
#include<iostream>
#include<cstring>
using namespace std;
class Set{
char *elements;
public:
Set() {
elements = new char('\0');
index = -1;
}
Set(const Set& cpy){
*this = cpy;
}
Set operator+(Set s){
Set temp = *this; // IMPORTANT! copy constructor of Set is called, "this" is passed as argument
// * = current OBJECT, else returns ADDRESS of current object
for(int i=0; s.elements[i] != '\0'; i++){
temp(s.elements[i]);
}
return temp;
}
Set& operator=(Set s){
delete [] elements;
elements = new char[strlen(s.elements) + 1];
strcpy(elements, s.elements); //overrides element of "this"
return *this;
}
};
精彩评论