【cpp语言】基础-2

class两个经典分类:

  • 不带指针
  • 带指针:数据带指针??
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef __MYSTRING__
#define __MYSTRING__

class String;

class String {
public:
String(const char* cstr = 0); //构造函数
String(const String& str); //拷贝构造
String& operator = (const String& str); //操作符重载--拷贝赋值
~String(); //析构函数:当类死亡时,此函数被构造
char* get_c_str() const { return m_data; } //普通成员函数
private:
char* m_data;
};

String::function(...)...
#endif

构造函数如何写:

1
2
3
4
5
6
7
8
9
10
11
inline
String::String(const char* cstr = 0) {
if (cstr) { //cstr指针是否是一个地址
m_data = new char[strlen(cstr) + 1];
strcpy(m_data, cstr);
}
else { //未指定初值
m_data = new char[1];
*m_data = '\0';
}
}

三大特殊函数:如果构造函数包含指针元素,那么类中需要包含拷贝构造,拷贝赋值与析构函数这三个函数。

  • 拷贝构造:若仅使用编译器默认的拷贝函数,它会逐位拷贝指针,这样相当于有两个指针均指向同一个位置,这样的操作存在一定的危险。为避免这种情况,我们
1
2
3
4
5
inline  //深拷贝
String::String(const String& str) {
m_data = new char [strlen(str.m_data) + 1]; //两个相同object之间互为友元
strcpy(m_data, str.m_data);
}
  • 拷贝赋值:
1
2
3
4
5
6
7
8
9
inline
String& String::operator = (const String& str) {
if (this == &str) return *this; //检测自我赋值

delete[] m_data; //清空原来的内存
m_data = new char[strlen(str.m_data) + 1]; //申请和str一样的内存
strcpy(m_data, str.m_data); //赋值
return *this;
}
  • 析构函数:
1
2
3
4
inline
String::~String(){
delete[] m_data;
}

堆栈与内存管理

1
2
3
4
5
6
class complex {...}
...
{
complex c1(1,2);
complex* p = new complex(3);
}

上面表示的是两种分配内存的方式,第一种为静态分配,故c1所在的内存存在于stack中,在stack中的内存在函数执行完毕就自动释放(如果是static变量,则在程序执行完毕后释放,若不是static变量,则在作用域结束时释放)。第二种方式表示的是在heap中申请一块大小和complex类一样的内存空间,这种是动态分配。动态分配的内存空间需要手动释放。

new:我们调用new函数时,一般是先分配一块内存空间,然后调用此类的析构函数初始化此类,最后返回该内存空间的起始地址。

1
2
3
4
String * ps;
void* mem = operator new (sizeof(String)); //分配内存,调用malloc(n)
ps = static_cast<String*>(mem); //转型
ps->String::String("hello"); //构造

delete:先调用析构函数,再释放内存空间。

1
2
String::~String(ps);    //析构函数
operator delete(ps); //释放内存,内部调用free(ps);

注:array new一定要搭配array delete

1
2
3
String* p = new String[3];  // array new
...
delete[] p; //array delete

【cpp语言】基础-2
http://example.com/2022/06/23/【cpp语言】基础-2/
作者
leegaojun
发布于
2022年6月23日
许可协议