Copy deep constructor with two pointer

I have been checking out why I have to do a deep copy constructor when my class has a pointer....until there It's fine...the trouble comes up when I have a class with two pointers...how I could manahe 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
  // copy constructor: deep copy
#include <iostream>
#include <string>
using namespace std;

class Example5 {
    string* ptr;
	string* pmr;
	
  public:
    Example5 (const string& str,const string& pqr) : ptr(new string(str)),pmr(new string(pqr)) {}
    ~Example5 () {delete ptr,delete pmr;}
    // copy constructor:
    Example5 (const Example5& x) {
		ptr = new string;
		pmr = new string;
		*pmr = *x.pmr;
		*ptr = *x.ptr;
	}
	// access content:
    void content(){
		cout<< this-ptr<<" ";
		cout<<this->pmr<<" ";
	}

};

int main () {
  Example5 foo ("Example","onemore");
  Example5 bar = foo;
  cout << "bar's content: " << bar.content() <<'\n';
  return 0;
}

It doesnt compile at all...
can It be because my parameter is not a const parameter, what I'm sending is an temporary object?
or maybe It doesnt make any sense to have two pointer or more since the goal of the pointer is to point the an object member of a class, the whole object itself...
If you are using std::string* pointers to play around with deep copying, fine. But I do hope you realise that new-ing std::string is not something you should ever do (and why.)

I can see 3 "stupid" mistakes in your code. I don't know (or recall) what compiler you are using, but the compiler error and warning messages should allow you to identify and fix them.

If you are using Visual C++ to build your apps you should be using at least warning level 4 (/W4 -- see project properties C/C++ / General page and set Warning Level to /W4 or /Wall, though /Wall can be a bit high if you're using Windows headers as well as standard C++ and C library headers.)

If you're using GCC then add -Wall -Wextra -pedantic to the compile options.

Andy
Last edited on
Yes, what I'm doing is playing around with the copy deep...I have got the example from the tutorial and I'm modifying a bit...I've got this code now..
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
  // copy constructor: deep copy
#include <iostream>
#include <string>
using namespace std;

class Example5 {
    
	string* ptr;
	string* pmr;
	
  public:
    Example5 (const string& str,const string& pqr) : ptr(new string(str)),pmr(new string(pqr)) {}
    ~Example5 () {delete ptr,delete pmr;}
    // copy constructor:
    Example5 (const Example5& x) {
		ptr = new string;
		pmr = new string;
		*pmr = *x.pmr;
		*ptr = *x.ptr;
	}
	
	    const string& content1() const {return *ptr;}
		const string& content2() const {return *pmr;}
};
	


int main () {
  Example5 foo ("Example","onemore");
  Example5 bar = foo;
  cout << bar.content1() <<" "<< bar.content2()<<"\n";
  
  return 0;
}


But I would like to print everything with just one function "content" but when I declare a function returning an object of that class, everything doesnt match...and to be honest I dont know yet why I should use new-ing std::string....
Your orginal Example5::content() method (on line 21 or your opening post) wasn't returning anything, so it's hardly surpising the compiler didn't like line 21, where you try to display the void return value.

And inside Example5::content() you:
1. have a typo on line 22 (I assume you meant this->ptr rather than this-ptr
2. are outputting the addresses of the pointers rather than the values they point to. (But I see that in the content1() and content2() methods of your newer version of the code you are dereferencing the pointers to obtains the values.)

But I would like to print everything with just one function "content" but when I declare a function returning an object of that class, everything doesnt match...

What about?

1
2
3
4
5
6
string content() const { // not does not return a const ref as str is a local string
    string str = *ptr;
    str += " ";
    str += *pmr;
    return str;
}


(have you looked into string manipulation yet, inc concatenation?)

But the better solution would be to overload operator<< for your type.

and to be honest I dont know yet why I should use new-ing std::string....

Why you should? Or shouldn't??

std::string is pretty much just a pointer wrapped up in a class so you don't have to worry about new-ing and deleting a char buffer.

1
2
3
4
5
6
7
class string {
private:
    char* data;
public:
     string() : data(nullptr) {}
     // etc
};


so by new-ing you are doing one more new, for the char buffer, than really needed. And making things more dangerous than required.

(real std::string implementations also keep track of the size, etc -- for optimization reasons -- but they should still be used directly and not via a pointer.)

Andy
Last edited on
Andy thanks for clearing me the situation...that's true there are so many option with the treatment of string...I'll have a better look, and as well there is other possibility to overload the operator << which I didnt realize.....however I'll have a better look of those things during this week...

now I have completed a code which has all the special members a class can have...but I'm having an issue and I'm afraid It comes from my move assignament or addition....
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
//Special members.

#include <stdio.h>
#include <iostream>

using namespace std; 

class integer{
	int* ptr;
	
	public:
		//default constructor
		integer():ptr(new int){};
		//destructor
		~integer(){delete ptr;}
		//constructor with int parameter
		integer (const int& x):ptr ( new int(x)){}
		//copy constructor
		integer(const integer& x):ptr(new int ( x.content())){}
		//copy assignment
		integer operator=(const integer& x){
			delete ptr;
			ptr = new int(x.content());
			return *this;
		}
		//move constructor
		integer (integer&& x):ptr(x.ptr){x.ptr = nullptr;}
		//move assignament
		integer operator=(integer&& x){
			delete ptr; 
			ptr = x.ptr;
			x.ptr=nullptr;
			return *this;
			
		}
		
		//access content
		const int& content()const {
			return *ptr;
		}
		//addition
		integer operator+(const integer& x){
			return integer(content()+x.content());
	
		
		
		
};

int main(){
	
	integer first = integer(5);
	integer second(2);
	integer third= second;
	cout<< "Content third"<<third.content()<<"\n";
	first = second;
	third = third + second;
	cout<<"content first"<<first.content()<<"\n";
	return 0;
}


there must be some mistake that I can't spot it...
.but I'm having an issue and I'm afraid It comes from my move assignament or addition....

Rather than saying "I'm having an issue" tell us about the issue. If your compiler won't compile the code, tell us what specific errors the compiler is generating when you try to compile.

For instance, when I copy and paste your code, then compile it I get the following error:

fatal error C1075: end of file found before the left brace '{' at 'xxx.cpp(8)' was matched


I look at that and I think... "Hey, must be missing a brace somewhere." So, look at your addition operator with that in mind.
yes, It was....but the error was launched at the main function, that's the reason I got confused....thank you..but It leads me to other question...., I know the error appears at the main function because the last operation in the main function uses the operator + overloaded, but why the compiler doesn't launch the error in the function operator +.....???
Why would you expect it to? The closing brace for operator+ is on line 48. What the compiler sees missing is the closing brace for the integer class. The error message I posted indicates that it can't find the right brace for the left brace appearing on line 8. (In xxx.cpp(8) 8 is the line number.)
Topic archived. No new replies allowed.