1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <iostream> #ifndef _BADSTRING_H_ #define _BADSTRING_H_ class BadString { private: char * str; int len; static int str_num; public: BadString(const char* s); BadString(); ~BadString(); //BadString & BadString::operator=(const BadString &st);//复制运算符重载 friend std::ostream & operator<<(std:: ostream & os,const BadString & st); }; #endif // DEBUG
1
2
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 "badstring.h" #include "cstring" using std::cout; using std::endl; int BadString::str_num = 0; BadString::BadString(const char * s) { len = strlen(s); str = new char[len + 1]; //str = s; strcpy(str, s); str_num++; cout <<"创建的对象个数为"<<str_num << ":"" << s << ""n"; } BadString::BadString() { len = 4; str = new char[4]; strcpy(str,"C++"); str_num++; cout << str_num << ":"" << str << ""默认构造函数n"; } BadString::~BadString() { cout <<"析构了对象"<< str; cout << "对象减少到" << str_num << endl; --str_num; delete[]str; } //显式复制构造函数 以进行深拷贝 //赋值运算符重载 ,解决类对象赋值是析构函数出现二次释放str //BadString & BadString::operator=(const BadString & st) //{ // if (this == &st) // { // return *this; // } // delete[] str; // len = st.len; // str = new char[len+1]; // std::strcpy(str,st.str); // return *this; //} //友元函数:非成员函数 但是与成员函数有相同权限 //std::ostream & operator << (std::ostream & os, const BadString & st) //{ // os << st.str; // return os; //}
main函数:
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#include "badstring.h" #include <iostream> using std::cout; using std::endl; void callme1(BadString & ); void callme2(BadString ); int main() { cout << "starting an inner block .n"; BadString name1("胡友呈1"); BadString name2("胡友呈2"); BadString name3("胡友呈3"); cout << "name1" << name1 << endl; cout << "name2" << name2 << endl; cout << "name3" << name3 << endl; callme1(name1); callme2(name2); BadString anther = name3;//anthor 被初始化为name3 使用复制构造函数 通过定义显示复制构造函数来进行深度复制 cout << "anthoer" << anther << endl; BadString knot; knot = name1;//赋值运算的重载 cout << "knot: " << knot << endl; cout << "exit the blockn"; cout << "End of main()n"; return 0; } void callme1(BadString & rsb) { cout << "String passed by reference :n"; cout << rsb << "n"; } void callme2(BadString sb) { cout << "String passed by value :n"; cout << sb << "n"; }
问题一:
main 函数中 callme2(name2)函数参数是按照值进行传递,导致callme2执行完了调用了析构函数。
使得对象name2已经释放,再次使用它时已经无法识别原始字符。
问题二:
本程序使用了一个对象来初始化另一个对象,编译器将自动生成其构造函数(称为复制构造函数),自动生成的构造函数并不知道更新静态变量num_string,因此打乱对象计数。
使用 一个对象来初始化另一个对象:
BadString anther = name3;
其对应的复制构造函数的原型:
BadString (const BadString &);
默认的复制构造函数逐个复制非静态成员(成为浅复制),复制的是成员的值。
下述语句:
BadString anther = name3;
可以等效为下面的功能(当然下面语句代码编译不能通过,因为私有成员是无法访问的):
BadString sailor;
sailor.str = sports.str;
sailor.len =sports.len;
使用默认复制构造函数导致的问题:
1)创建对象计数并未增加
2)anther已经将name3的字符串析构,而name3再次析构会导致字符串无法找到其地址出现乱码。
通过显示构造函数解决该问题。
问题三:
赋值运算符重载:
kont =name1;
当函数正常调用kont 析构函数 ,其显示正常
但是name1 进行析构释放的时候就会出现乱码,因为kont.str 与name1.str指向的地址相同
通过重构=提供赋值运算符的定义。
对于上述问题进行:
解决方案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <iostream> #ifndef _BADSTRING_H_ #define _BADSTRING_H_ class BadString { private: char * str; int len; static int str_num; public: BadString(const char* s); BadString(const BadString & s); BadString(); ~BadString(); BadString & BadString::operator=(const BadString &st); friend std::ostream & operator<<(std:: ostream & os,const BadString & st); }; #endif // DEBUG
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 "badstring.h" #include "cstring" using std::cout; using std::endl; int BadString::str_num = 0; BadString::BadString(const char * s) { len = strlen(s); str = new char[len + 1]; //str = s; strcpy(str, s); str_num++; cout <<"创建的对象个数为"<<str_num << ":"" << s << ""n"; } BadString::BadString(const BadString & s) { str_num++; len = s.len; str = new char[len + 1]; std::strcpy(str, s.str); cout << "创建的对象个数为" << str_num << ":"" << s << ""n"; } BadString::BadString() { len = 4; str = new char[4]; strcpy(str,"C++"); str_num++; cout << str_num << ":"" << str << ""默认构造函数n"; } BadString::~BadString() { cout <<"析构了对象"<< str; cout << "对象减少到" << str_num << endl; --str_num; delete[]str; } //显式复制构造函数 以进行深拷贝 //赋值运算符重载 ,解决类对象赋值是析构函数出现二次释放str BadString & BadString::operator=(const BadString & st) { if (this == &st) { return *this; } delete[] str; len = st.len; str = new char[len+1]; std::strcpy(str,st.str); return *this; } //友元函数:非成员函数 但是与成员函数有相同权限 std::ostream & operator << (std::ostream & os, const BadString & st) { os << st.str; return os; }
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#include "badstring.h" #include <iostream> using std::cout; using std::endl; void callme1(BadString & ); void callme2(BadString & ); int main() { { cout << "starting an inner block .n"; BadString name1("张三 1 号 "); BadString name2("张三 2 号 "); BadString name3("张三 3 号 "); cout << "name1" << name1 << endl; cout << "name2" << name2 << endl; cout << "name3" << name3 << endl; callme1(name1); cout << "name1" << name1 << endl; callme2(name2); cout << "name2" << name2 << endl; BadString anther = name3;//anthor 被初始化为name3 使用复制构造函数 通过定义显示复制构造函数来进行深度复制 cout << "anthoer" << anther << endl; BadString knot; knot = name1;//赋值运算的重载 cout << "knot: " << knot << endl; cout << "exit the blockn"; } cout << "End of main()n"; return 0; } void callme1(BadString & rsb) { cout << "String passed by reference :n"; cout << rsb << "n"; } void callme2(BadString & sb) { cout << "String passed by value :n"; cout << sb << "n"; }
最后
以上就是寂寞棒棒糖最近收集整理的关于默认复制构造函数 默认 赋值运算符产生的问题的全部内容,更多相关默认复制构造函数内容请搜索靠谱客的其他文章。
发表评论 取消回复