概述
#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
#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函数:
#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指向的地址相同
通过重构=提供赋值运算符的定义。
对于上述问题进行:
解决方案:
#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
#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;
}
#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";
}
最后
以上就是寂寞棒棒糖为你收集整理的默认复制构造函数 默认 赋值运算符产生的问题的全部内容,希望文章能够帮你解决默认复制构造函数 默认 赋值运算符产生的问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复