静态成员初始化:
不可以在类的内部对静态成员进行初始化;类声明只是描述内存将如何分配,实际并没有进行内存分配;静态作为分离部分存储,而不是作为对象的一部分一同存储;
初始化时指明域和和类型,关键字static不需要使用;在函数定义文件中对静态成员初始化。
静态成员函数优点:
不需要由对象调用,直接使用类调用;
因为静态没有与对象关联,所以无法访问对象的成员,只能访问静态的成员
自动化存储对象delete的顺序跟create顺序相反;
C++自动如下成员函数:
如果没有定义构造函数,则默认体提供构造函数
Klunk::Klunk() { } //隐式构造函数
Klunk lunk; //调用默认构造函数;
构造函数带有参数,但是参数有默认值,这样的构造函数也视为默认构造函数
如果没有定义构造函数,默认提供默认析构函数
提供默认拷贝构造函数;
新对象被创建,使用存在的对象进行初始化时调用赋值构造函数;将对象以值传递的方式传给函数时调用
提供默认赋值操作符函数
提供地址操作符函数;
C++11提供特殊的成员函数:移动构造函数和移动赋值操作符
class StringBad {
private:
char *str; //字符指针而不是字符数组
int len;
static int string_num;
public:
StringBad();
StringBad(char *s, int len);
};
int StringBad::string_num = 0;
StringBad::StringBad(const char *s) {
len = strlen(s);
str = new char[len+1];
// str = s; //单纯存储s指针,并没有进行拷贝;
strcpy(str, s);
num_string++;
}
StringBad:~StringBad() //使用构造函数释放分配的内存;
{
string_num--;
delete[] str; // 此语句至关重要
}
// 显示定义拷贝构造函数
StringBad::StringBad(StringBad &o){
string_num++;
len = o.len;
s = new char[len + 1];
strcpy(s, o.str);
}
StringBad &operator=(const StringBad &st)
{
string_num++;
len = o.len;
s = new char[len + 1];
strcpy(s, o.str);
return *this;
}
callMe1(StringBad &rsb); //引用传递;
callMe2(StringBad dsb); //值传递,导致触发析构操作
//限制在内部代码块中使用,当离开此范围,自动调用解析函数,如果在外部代码块中调用,可能导致内存泄漏。
//问题: 字符串并没有存储在Object对象中,而是存储在另一个地方;//使用生成的拷贝构造函数,
--正确的String代码-----
String::String()
{
len = 0;
str = new char[1];
str[0] = '\0';
}
String::~String()
{
delete [] str;
}
bool String::operator<(const String &s1, const String &s2)
{
return (strcmp(s1.str, s2.str) < 0) ;
}
bool String::operator>(const String &s1, const String &s2)
{
return s2 < s1;
}
bool String::operator==(const String &s1, const String &s2)
{
return (strcmp(s1.str, s2.str) == 0);
}
char String::operator[](int i)
{
return str[i];
}