静态成员
静态成员(数据成员、成员函数)通过static关键字定义。
静态数据成员
每个类只有一个拷贝,由该类的所有对象共同维护和使用。
静态成员必须初始化。静态成员变量要在类的外部初始化,不能使用初始化列表;静态常量可以在类的内部初始化。
公有静态成员可以直接通过类名访问。
class Children
{
private:
char m_name[30];
public:
// 定义静态数据成员
static int m_count;
// 静态常量可以在类的内部初始化,也可以在类型的外部初始化。
const static int m_age = 6;
Children(const char* name)
{
strcpy_s(m_name, 30, name);
// 每创建一个对象m_count增加1,m_count的值是Children类创建的对象的个数
m_count ++;
}
void show()
{
// 静态成员可以在普通方法中访问。
cout << &m_name << " : " << m_name << ", " << &m_count<< " : " << m_count << ", " << m_age << endl;
}
};
// 静态成员变量必须在类的外部初始化
int Children::m_count = 0;
/*
静态成员常量也可以在外部初始化
const int Children::m_age = 10;
*/
int main()
{
Children c1("Tom");
c1.show();
Children c2("Tom1");
/*
静态成员每个类只有一个拷贝,由该类的所有对象共同维护和使用。
通过c1和c2访问m_count,得到相同的结果
*/
c2.show();
c1.show();
// 公有静态数据成员可以直接通过 类名::成员名 访问。常用于访问静态常量。
Children::m_count = 10;
c1.show();
return 0;
}
静态成员函数
静态成员函数只能访问静态数据成员,只能调用静态成员函数。
公有静态成员函数可以通过类名直接访问,也可以通过这个类的对象访问。
class Children
{
private:
char m_name[30];
static int m_count;
public:
Children(const char* name)
{
strcpy_s(m_name, 30, name);
m_count++;
}
void show()
{
cout << &m_name << " : " << m_name << endl;
// 普通方法可以调用静态方法,也可以使用静态变量
showStatic();
}
/*
定义静态成员函数
*/
static int getCount()
{
return m_count;
}
static void showStatic()
{
/*
静态成员函数只能访问静态成员
m_name; 不允许
show(); 不允许
*/
cout << m_count << ", " << getCount() << endl;
}
};
int Children::m_count = 0;
int main()
{
Children c1("Tom");
cout << "c1.getCount(): " << c1.getCount() << endl;
// 静态成员函数可以通过类名直接访问
cout << "Children::getCount(): " << Children::getCount() << endl;
c1.show();
Children::showStatic();
return 0;
}
常对象与常成员函数
常对象
属性值不能修改的对象是常对象。
常对象不能使用非常成员函数;常对象不允许修改公有属性。
class Dog
{
public:
int m_age;
Dog(int age)
{
m_age = age;
}
void setAge(int age)
{
m_age = age;
}
// 定义常函数
void show() const
{
cout << "m_age: " << m_age << endl;
}
};
int main()
{
// 定义常对象
const Dog d1(10);
/*
d1.m_age = 6; 不能给常对象公有属性赋值
d1.setAge(7); 常对象上不能访问非常函数
*/
// 可以获取常对象的公有属性的值
cout << d1.m_age << endl;
// 常对象只能访问常函数
d1.show();
return 0;
}
常成员函数
在常成员函数中,不能修改对象的属性值,也不能调用该类的非常成员函数。
常成员函数可以调用静态成员函数,也可以访问静态成员变量。
普通对象既可以调用普通函数成员也可以调用常函数成员 ,但会优先调用普通成员函数。
class Dog
{
private:
int m_age;
static int m_count;
public:
Dog(int age)
{
m_age = age;
m_count++;
}
void setAge(int age)
{
m_age = age;
}
int getAge() const
{
/*
常成员函数不能修改属性的值
m_age++;
常成员函数可以访问属性,获取属性的值
*/
return m_age;
}
static int getCount()
{
return m_count;
}
// 定义非常函数show
void show()
{
setAge(1);
m_age++;
cout << "void show() :: m_age: " << getAge() << " m_count: " << m_count << " getCount: " << getCount() << endl;
}
// 定义常函数show
void show() const
{
/*
常函数只能调用常函数,不能调用非常函数。
setAge(1);
常函数中可以调用静态函数,也可以访问(赋值)静态变量。
*/
cout << "void show() const :: m_age: " << getAge() << " m_count: " << m_count << " getCount: " << getCount() << endl;
}
};
int Dog::m_count = 0;
int main()
{
Dog d1(1);
d1.show();
const Dog d2(2);
d2.show();
return 0;
}
对象数组
存放对象的数组。
class Dog
{
private:
int m_age = 0;
public:
Dog()
{
}
Dog(int age)
{
m_age = age;
}
void show()
{
cout << "m_age: " << m_age << endl;
}
};
int main()
{
// 使用无参构造函数创建对象数组
Dog d[3];
for (int i = 0; i < 3; i++)
{
d[i].show();
}
// 使用有参构造函数创建对象数组
Dog d1[3] = { Dog(1), Dog(2), Dog(3) };
for (int i = 0; i < 3; i++)
{
d1[i].show();
}
// 对象数组的数组名是对象数组第一个元素的地址。
d1->show(); // 对象指针可以使用->操作访问对象成员。
return 0;
}
对象指针
对象指针就是用于存放对象地址的变量。
this指针
this指针是指向对象本身的指针。
不能通过this指针访问静态成员。
this指针常用于:
成员函数的参数变量名和类属性同名时
在类的非静态成员函数中返回对象本身
class Teacher
{
private:
int id;
int age;
public:
Teacher(int id, int age)
{
// 成员变量与参数同名时,使用this指针访问成员变量。
this->id = id;
this->age = age;
}
Teacher& operator=(const Teacher& teacher)
{
// 判断是不是对象本身
if (this != &teacher)
{
id = teacher.id;
age = teacher.age;
}
// 返回对象本身
return *this;
}
Teacher& addStudent()
{
cout << "添加了一个学生" << endl;
// 返回对象本身
return *this;
}
void show()
{
cout << id << ", " << age << endl;
}
};
int main()
{
Teacher teacher(10000, 28);
// 由于addStudent()返回teacher对象本真,所以调用后可以再次使用.操作符访问teacher的方法。
teacher.addStudent().addStudent().addStudent();
// show没有返回值,调用后不能使用.操作符调用其他成员。
teacher.addStudent().show();
return 0;
}