197-C++重要知识点11

本文探讨了C++中常方法与普通方法的调用规则,强调了权限收缩与扩展的概念,并举例说明了const_cast在去常性转换中的应用。接着介绍了realloc函数在内存动态扩展中的作用,以及如何处理原有数据的迁移。最后,自定义了一个String类,详细阐述了其构造、赋值、引用计数和字符串操作等实现细节,包括加法运算符重载和内存管理策略。
摘要由CSDN通过智能技术生成

1.判断下面普通方法调用常方法和常方法调用普通方法,哪个是正确的

class Object
{
private:
	int value;
public:
	Object(int x = 0):value(x)  {}
	~Object() {}
	
	void print() const
	{
		cout << value <<endl;
		fun();
	}
	void fun()
	{
		print();
		value += 1;
	}
};

print是一个常方法,它的指针为const Objcet * const this;,fun是一个普通方法,它的指针为Object * cosnt this;fun可以调用print,权限收缩,但是print不能调用fun,即权限不能扩展

当我们调用fun函数时,fun();就相当于this->fun()就相当于fun(this);

可以通过去常性强转,进而print方法可以调用fun方法,即const_cast<Object *>的方式

C++用const_cast强转而不用C语言的方式强转的原因就是const_cast的目的明确,就是去常性,而C语言的方式目的不明确

2.realloc函数的使用

int main()
{
    int* ip = (int*)malloc(sizeof(int) * 5);
    for (int i = 0; i < 5; i++)
    {
        ip[i] = i;
        printf("%d ", ip[i]);
    }
    printf("\n");
    ip = (int*)realloc(ip, sizeof(int) * 10);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", ip[i]);
    }
    printf("\n");
    return 0;
}

realloc函数的作用,在原有的基础上开辟空间,如果后面的空间足够大,就直接在后面开辟空间,如果原有的空间不足够大,就另外新开辟一块空间,并且把之前的内容拷贝到新开辟的空间中,即原来的数据并不会丢失

3.String类

class String
{
protected:
	struct StrNode
	{
		int ref;  // 引用计数
		int len;  // 字符串的长度
		int size; // 柔性数组的容量
		char data[];
	};
private:
	StrNode* pstr;
	String(StrNode* p) :pstr(p) {}
public:
	String(const char* p = NULL) :pstr(NULL)
	{
		if (p != NULL)
		{
			int sz = strlen(p);
			pstr = (StrNode*)malloc(sizeof(StrNode) + sz * 2 + 1);
			pstr->ref = 1;
			pstr->len = sz;
			pstr->size = sz * 2;
			strcpy(pstr->data, p);
		}
	}
	~String()
	{
		if (pstr != NULL && --pstr->ref == 0)
		{
			free(pstr);
		}
		pstr = NULL;
	}
	String(const String& str) :pstr(NULL)
	{
		if (str.pstr != NULL)
		{
			pstr = str.pstr;
			pstr->ref += 1;
		}
	}
	String& operator=(const String& s)
	{
		if (this == &s) return *this;
		if (this->pstr != NULL && --this->pstr->ref == 0)
		{
			free(this->pstr);
		}
		this->pstr = s.pstr;
		if (this->pstr != NULL)
		{
			this->pstr->ref += 1;
			//s.ptr->ref += 1;
		}
		return *this;
	}

	char operator[](const int index) const 
	{
		assert(pstr != NULL && index >= 0 && index <= pstr->len - 1);
		return pstr->data[index];
	}
	void modify(const int index, const char ch)
	{
		assert(pstr != NULL && index >= 0 && index <= pstr->len - 1);
		if (pstr->ref > 1)
		{
			int total = sizeof(StrNode) + pstr->size + 1;
			StrNode* newnode = (StrNode*)malloc(total);
			memmove(newnode, pstr, total);
			newnode->ref = 1;
			pstr->ref -= 1;
			pstr = newnode;
		}
		pstr->data[index] = ch;
	}
	ostream& operator<<(ostream& out) const
	{
		if (pstr != NULL)
		{
			out << pstr->data;
		}
		return out;
	}
	String(String&& s) :pstr(NULL)
	{
		pstr = s.pstr;
		s.pstr = NULL;
	}
	String& operator=(String&& s)
	{
		if (this == &s) return *this;
		if (pstr != NULL && --pstr->ref == 0)
		{
			free(pstr);
		}
		pstr = s.pstr;
		s.pstr = NULL;
		return *this;
	} // s1 = s2;

	 String  operator+(const String& s)const
	 {
		 if (pstr == NULL && s.pstr == NULL)
		 {
			 return String();
		 }
		 else if (pstr != NULL && s.pstr == NULL)
		 {
			 return *this;
		 }
		 else if (pstr == NULL && s.pstr != NULL)
		 {
			 return s;
		 }
		 else
		 {
			 int total = (pstr->len + s.pstr->len)*2;
			 StrNode* newsp = (StrNode*)malloc(sizeof(StrNode) + total + 1);
			 strcpy(newsp->data, pstr->data);
			 strcat(newsp->data, s.pstr->data);
			 newsp->ref = 1;
			 newsp->len = pstr->len + s.pstr->len ;
			 newsp->size = total;
			 return String(newsp);
		 }
	 }
	
	 String& operator+=(const String& s)
	 {   // s1+= s3;
		 if (this->pstr != NULL && s.pstr != NULL)
		 {
			 if (this->pstr->ref > 1) // s1=>string  == 1
			 {
				 int total = pstr->len + s.pstr->len;
				 this->pstr->ref -= 1;
				 char* tmp = this->pstr->data; //
				 this->pstr = (StrNode*)malloc(sizeof(StrNode) + total * 2 + 1);
				 strcpy(this->pstr->data, tmp);
				 strcat(this->pstr->data, s.pstr->data);
				 this->pstr->ref = 1;
				 this->pstr->len = total;
				 this->pstr->size = total * 2;
			 }else 
			 {//s1 +=s3
				 int total = this->pstr->len + s.pstr->len;
				 if (this->pstr->size < total)
				 {
					 this->pstr = (StrNode*)realloc(this->pstr, sizeof(StrNode) + total * 2 + 1);
					 this->pstr->size = total * 2;
				 }
				 strcat(this->pstr->data, s.pstr->data);
				 this->pstr->len = total;
			 }
		 }else  if (this->pstr == NULL && s.pstr != NULL)
		 {
			 this->pstr = s.pstr;
			 this->pstr->ref += 1;
		 }
		 return *this;
	 }
};
ostream& operator<<(ostream& out, const String& s)
{
	s << out;
	return out;
}
int main()
{
	String s1("yhping");
	
	String s3("newdatanewdata");

	s1 += s1;// 程序80%用于分析,15%用于编写,5%用来改错
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值