对象的使用
一、static关键字
·对于特定类型的全体对象而言,有时候可能需要需要访问一个全局的变量。
比如说统计某种类型对象已创建的数量。
·如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个
全局变量,这时我们可以用类的静态成员来解决这个问题。
·非static数据成员存在于类类型的每个对象中,static数据成员独立于该类
的任意对象存在,它是与类关联的对象,不与类对象关联。
static成员需要在类定义体外进行初始化与定义:
代码示例:
String.h:
#ifndef _STRING_H_
#define _STRING_H_
#include <iostream>
using namespace std;
class String
{
public:
static int MAX_LEN;
private:
};
#endif
String.cpp:
#include <iostream>
#include "String.h"
using namespace std;
int String::MAX_LEN = 1024;
Main.c:
#include <iostream>
#include "String.h"
using namespace std;
int main()
{
cout << String::MAX_LEN << endl;
return 0;
}
运行结果:
Static是不属于某个具体对象的,它像成员方法一样是可以共享的。
可以在main.c中 cout << sizeof(String) << endl;来验证(自行验证)
此处举例用成员方法初始化static变量:
string.h:
#ifndef _STRING_H_
#define _STRING_H_
#include <iostream>
using namespace std;
class String
{
public:
//static int MAX_LEN;
String();
String(char * str);
~String();
String(const String& other);
String& operator=(const String& other);
void Display();
void setMAXLEN(int maxlen);
int getMAXLEN();
private:
static int MAX_LEN;
char *str_;
};
#endif
String.cpp
#include <iostream>
#include "String.h"
using namespace std;
int String::MAX_LEN = 1024;
void String::setMAXLEN(int maxlen)
{
MAX_LEN = maxlen;
}
int String::getMAXLEN()
{
return MAX_LEN;
}
String::String()
{
str_ = new char('\0');
cout << "default constructor String!" << endl;
}
String::String(char * str)
{
cout << "constructor String!" << endl;
int len = strlen(str) + 1;
str_ = new char(len);
memset(str_, 0, len);
strcpy(str_, str);
}
String :: ~String()
{
cout << "destory String!" << endl;
}
String::String(const String& other)
{
int len = strlen(other.str_) + 1;
str_ = new char(len);
memset(str_, 0, len);
strcpy(str_, other.str_);
}
String& String :: operator=(const String& other)
{
if (this == &other)
{
return *this;
}
int len = strlen(other.str_) + 1;
delete[] str_;
str_ = new char(len);
memset(str_, 0, len);
strcpy(str_, other.str_);
return *this;
}
void String::Display()
{
cout << str_ << endl;
}
main.c
#include <iostream>
#include "String.h"
using namespace std;
int main()
{
String s1;
s1.setMAXLEN(2048);
cout << s1.getMAXLEN() << endl;
return 0;
}
运行结果:
static成员的优点:
·static 成员的名字是在类的作用域中,因此可以避免与其他类成员或全局对象
名字冲突
·可以实施封装,static成员可以是私有的,而全局对象不可以
·阅读程序容易看出static成员与某个类相关联,这种可见性可以清晰地反映程
序员的意图。
static cost成员的使用:
整型static const 成员可以在类定义体中初始化,该成员可以不在类体外进行定义。
static成员函数:
·static 成员函数没有this指针
·非静态成员函数可以访问静态成员
·静态成员函数不可以访问非静态成员
static总结:
1.用于函数内部修饰变量,即函数内的静态变量。这种变量的生存期长于该函数,使得函数具有一定的“状态”。使用静态变量的函数一般是不可重入的,也不是线程安全的的,比如strtok(3)
2.用在文件级别(函数体之外),修饰变量或函数,表示该变量或函数只在本文件可见,其他文件看不到也访问不到该变量或函数。
二、const 关键字
1.const成员函数:
·const成员函数不会修饰对象的状态
·const成员函数只能访问数据成员的值,而不能修改它。
2.const对象
如果一个对象指定为const,就是告诉编译器不要修改它。
·const对象的定义:
const 类名 对象表(参数表)
·const对象不能调用非const成员函数
·const修饰指针,指针的地址不可变,指向的空间里的值可变!
三、mutable关键字
·用mutable修饰的数据成员即使在const对象或在const成员函数中都可以被
修改。
四、扩展
1.类/对象大小的计算
·类大小计算遵循前面学过的结构体对齐原则
·类的大小与数据成员有关与成员函数无关
·类的大小与静态数据成员无关
·虚函数对类的大小无关
·虚继承对类的大小的影响
2.对象作用域与生存期
·栈对象
隐含调用构造函数(程序中没有显示调用)
·堆对象
隐含调用构造函数(程序中没有显示调用)
·全局调用、静态全局对象
全局对象的构造先于main函数
已初始化的全局变量或静态全局对象存储于.data段中
未初始化的全局变量或静态全局对象存储于.bss段中
·静态局部对象
已初始化的静态局部变量存储于.data段中
未初始化的静态局部变量存储于.bss段中