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;
}