我是靠谱客的博主 寂寞棒棒糖,这篇文章主要介绍默认复制构造函数 默认 赋值运算符产生的问题,现在分享给大家,希望可以做个参考。

复制代码
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"; }









最后

以上就是寂寞棒棒糖最近收集整理的关于默认复制构造函数 默认 赋值运算符产生的问题的全部内容,更多相关默认复制构造函数内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部