为了实现引用技术,想必大家都考虑过如下几种方法
1. 使用非静态成员变量(int类型)计数器, 此方法导致每个类都拥有一个独立的计数器, 而在对象进行拷贝时, 新对象可能需要对原有计数器进行引用并修改其值,这就导致了计数器之间缺乏共通性
2.使用静态成员计数器, 此方法虽然解决了对象直接的共通性, 但导致的结果是我们在定义两个不同的对象,如String("1111")和 String("2222"), 这两个对象明显需要使用不同的内存块, 此时应使用各自独立版本的计数器
3.那么如何使成员计数器即具备共通性,同时又具备独立性呢? 答案是:使用成员指针,成员指针即可以指向各个拷贝版本共同的计数器对应的内存块,又可以各自指向不同的计数器内存块, 此方法可以完美解决上述问题
代码如下:
//String.h
#ifndef STRING_H
#define STRING_H
#include <ostream> //本想不在头文件中引用该头文件的, 主要是达到减少循环依赖性的可能, 虽然没必要, 但是养成一个习惯也是好的
//namespace std //这样声明报错了, 所以注释掉了, 原因应该是因为ostream是用typedef取的类型别名吧
//{
// class ostream;
//}
class String
{
public:
String();
String(const char* pstr);
String(const String& str);
String& operator=(const String& str);
char& operator[](int index);
const char& operator[](int index)const; //只读版本
friend std::ostream& operator<<(std::ostream& os, const String& str);
~String();
private:
int* count; //计数器
char* cstr; //字符串
};
#endif // STRING_H
//String.cpp
#include "String.h"#include <cstring>
#include <cassert>
String::String()
{
count = new int(1);
cstr = new char('\0');
}
String::String(const char* pstr)
{
cstr = new char[strlen(pstr) + 1];
count = new int(1);
// if(NULL == pstr)
// *cstr = '\0';
strcpy(cstr, pstr);
}
String::String(const String& str)
{
cstr = str.cstr;
count = str.count;
++(*count);
}
String& String::operator=(const String& str)
{
if(this == &str)
return *this;
if(1 == *count)
{
delete []cstr;
delete count;
}
count = str.count;
cstr = str.cstr;
return *this;
}
char& String::operator[](int index)
{
int len = strlen(cstr);
assert(index >= 0 && index <= len);
if(1 == *count)
return *(cstr + index);
--(*count);
count = new int(1);
char* temp = cstr;
cstr = new char[len + 1];
strcpy(cstr, temp);
return *(cstr + index);
}
const char& String::operator[](int index) const
{
int len = strlen(cstr);
assert(index >= 0 && index <= len);
return *(cstr + index);
}
std::ostream& operator<<(std::ostream &os, const String &str)
{
os << str.cstr;
return os;
}
String::~String()
{
--(*count);
if(0 == *count)
{
delete[]cstr;
delete count;
}
}
//main.cpp
#include <iostream>
#include "String.h"
using namespace std;
int main()
{
String a;
cout << a << endl;
String b("asdf");
cout << b << endl;
a = b;
cout << a << endl;
return 0;
}