一、深拷贝与浅拷贝
浅拷贝就是对象的数据成员之间的简单赋值,浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。举个例子,一个人一开始叫张三,后来改名叫李四了,可是还是同一个人。
代码例程:
#ifndef _STRING_H_
#define _STRING_H_
class String
{
public:
String();
~String();
void Display();
String(const String& other);
String(char* str);
private:
char *str_;
};
#endif
#include<iostream>
#include"String.h"
using namespace std;
String::String()
{
cout<<"constructing......."<<endl;
}
String::~String()
{
cout<<"destory test!"<< endl;
}
String::String(char *str)
{
cout<<"constructor"<<endl;
int len = strlen(str)+1;
str_ = new char[len];
memset(str_,0,len);
strcpy(str_,str);
}
String::String(const String& other )//浅拷贝
{
str_ = other.str_;
}
void String::Display()
{
cout<< str_ <<endl;
}
#include<iostream>
#include"String.h"
using namespace std;
int main()
{
String s1("hello");
s1.Display();
String s2(s1);
s2.Display();
return 0;
}
结果:
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。
例程:
#ifndef _STRING_H_
#define _STRING_H_
class String
{
public:
String();
~String();
void Display();
String(const String& other);
String(char* str);
String& operator=(const String& other);
private:
char *str_;
};
#endif
#include<iostream>
#include"String.h"
using namespace std;
String::String()
{
cout<<"constructing......."<<endl;
}
String::~String()
{
cout<<"destory test!"<< endl;
}
String::String(char *str)
{
cout<<"constructor"<<endl;
int len = strlen(str)+1;
str_ = new char[len];
memset(str_,0,len);
strcpy(str_,str);
}
String::String(const String& other)//深拷贝
{
int len = strlen(other.str_)+1;
str_ = new char[len];
memset(str_,0,len);
strcpy(str_,other.str_);
}
String& String::operator=(const String& other)//赋值重载
{
if(this == &other)
{
return *this;
}
int len = sizeof(other.str_)+1;
delete []str_;//删除原来的字符串
str_ = new char[len];
memset(str_,0,len);
strcpy(str_,other.str_);
// return str_;
}
void String::Display()
{
cout<< str_ <<endl;
}
#include<iostream>
#include"String.h"
using namespace std;
int main()
{
String s3("world");
s3 = "hello";
s3.Display();
return 0;
}
结果:
当类里有指针对象时,要对指针进行深层拷贝,运算符也要进行深层拷贝。
如果要禁止拷贝,将拷贝构造函数放在private里,将其私有化。
二、默认生成的函数
三、对象的使用
1、static关键词
用static修饰的类成员,常用来做统计某种类型变量已经创建的数量。
被static修饰的数据成员不能再构造函数中初始化,也不能在初始化列表中初始化,只能在类外初始化,但不是绝对的,加上const是可以在类内初始化的。
如:static const int MaxLen = 1024;
并且该成员不只属于某个对象的成员,所有对象都可以引用它,如果改变它的值,则在各对象中这个数据成员的值都同时改变了。
被static修饰的静态成员函数没有this指针,静态成员函数是类的一部分而不是对象的一部分,如果在类外调用公用的静态成员函数,要用类名和域运算符“::”,
如:static int volume();
Box::volume();
A.volume();
静态成员函数主要用来访问静态数据成员,而不是非静态成员。但是如果一定要引用本类的费静态成员,应该加对象名和成员运算符“.”,如:cout<<a.width<<endl;//引用本类对象a中的非静态成员。
例程:
#ifndef _STRING_H_
#define _STRING_H_
class String
{
public:
//static int MaxLen;//类外初始化
String();
~String();
void Display() const;
String(const String& other);
String(char* str);
void SetMaxLen(int MaxLen);
int GetMaxLen();
private:
char *str_;
static int MaxLen_;
};
#endif
#include<iostream>
#include"String.h"
using namespace std;
int String::MaxLen_ = 0;
void String::SetMaxLen(int MaxLen)
{
MaxLen_ = MaxLen;
}
int String::GetMaxLen()
{
return MaxLen_;
}
String::String()
{
cout<<"constructing......."<<endl;
}
String::~String()
{
cout<<"destory test!"<< endl;
}
String::String(char *str)
{
cout<<"constructor"<<endl;
int len = strlen(str)+1;
str_ = new char[len];
memset(str_,0,len);
strcpy(str_,str);
}
String::String(const String& other)
{
str_ = other.str_;
}
void String::Display() const
{
cout<< str_ <<endl;
}
#include<iostream>
#include"String.h"
using namespace std;
int main()
{
String s1("hello world");
String s2(s1);
String s;
s.SetMaxLen(1024);
cout<<s.GetMaxLen()<<endl;
return 0;
}
2、const关键词
Const修饰成员函数:不会修改对象的状态,只能访问数据成员的值
用法: void Display() const;
Const修饰的成员若是指针,指针的地址不可以改变,但是可以修改指针的值
Const对象不能调用非const成员函数。
3、mutable关键词
用mutable修饰的成员即使在const对象或const成员函数均可以修改。
#ifndef _STRING_H_
#define _STRING_H_
class String
{
public:
//static int MaxLen;//类外初始化
String();
~String();
void Display() const;
String(const String& other);
String(char* str);
void SetMaxLen(int MaxLen);
int GetMaxLen();
private:
mutable char *str_;
static int MaxLen_;
};
#endif
#include<iostream>
#include"String.h"
using namespace std;
int String::MaxLen_ = 0;
void String::SetMaxLen(int MaxLen)
{
MaxLen_ = MaxLen;
}
int String::GetMaxLen()
{
return MaxLen_;
}
String::String()
{
cout<<"constructing......."<<endl;
}
String::~String()
{
cout<<"destory test!"<< endl;
}
String::String(char *str)
{
cout<<"constructor"<<endl;
int len = strlen(str)+1;
str_ = new char[len];
memset(str_,0,len);
strcpy(str_,str);
}
String::String(const String& other)
{
str_ = other.str_;
}
void String::Display() const
{
str_ = "123";
cout<< str_ <<endl;
}
#include<iostream>
#include"String.h"
using namespace std;
int main()
{
String s1("hello");
// String s2(s1);
s1.Display();
String s;
s.SetMaxLen(1024);
cout<<s.GetMaxLen()<<endl;
return 0;
}