注意:全缺省的有参构造函数可以实现默认(无参)构造函数的功能。
const修饰的成员函数:叫做常方法,本质是在this指针前面加上const变成了常量指针常量,这样导致指向的值和指向都不能修改,所以常方法无法修改成员变量,对象前加const就是常对象,常对象只能调用常方法。
加了mutable关键字的成员变量可以被常方法修改,因而也可以在常对象中被修改。
#include<iostream>
using namespace std;
class Person
{
public:
Person(const char* name, int age)
{
strcpy(m_name, name);
m_age = age;
}
const char* getName() const
{
return this->m_name;
}
void setName(const char* name)
{
strcpy(this->m_name, name);
}
int getAge() const
{
return this->m_age;
}
void setAge(int age) const
{
//this->m_name = "CCC";//常方法不能修改成员变量
this->m_age = age;//加了mutable的成员变量可以被常对象修改,因此可以被常方法修改
}
private:
char m_name[10];
mutable int m_age;
};
int main()
{
const Person p("AAA", 18);
p.getName();//常对象只能调常方法
//p.setName("CCC");//报错, 常对象不允许修改成员变量
p.getAge();
p.setAge(18);
system("pause");
return 0;
}
类的相关概念:
1.C语言结构体不支持定义函数,C++结构体支持定义函数。
2.C++结构体的默认访问权限为公有,C++类的默认访问权限为私有。
类的两种定义方式,类内直接定义和类内声明类外定义,也可以分文件编写(在.h内声明类成员函数,在.cpp内实现类的成员函数)。注意要加作用域限定符。
Person.h
#include<iostream>
using namespace std;
class Person
{
public:
Person(const char* name="CCC", int age=16);
Person(const Person& p);
Person& operator=(const Person& p);
~Person();
private:
char m_name[10];
int m_age;
};
Person.cpp
#include"Person.h"
Person::Person(const char* name="CCC", int age=16)
{
strcpy(this->m_name, name);
this->m_age = age;
}
Person::Person(const Person& p)
{
strcpy(this->m_name, p.m_name);
this->m_age = p.m_age;
}
Person& Person::operator=(const Person& p)
{
if (this != &p)
{
strcpy(this->m_name, p.m_name);
this->m_age = p.m_age;
}
return *this;
}
Person::~Person() {}
main.cpp
#include<iostream>
#include"Person.h"
using namespace std;
int main()
{
Person p1("AAA", 18);
Person p2 = p1;
Person p3;
p3 = p2;
return 0;
}
3.类的访问权限限定符:对象在类外只能访问类的公有成员,无法访问类的私有和保护成员。
一个类可以实例化多个对象,类更像是一个模型,编译器本身并没有分配内存空间来存储它,只有实例化对象后才有了实际的物理空间来存储成员变量。空类大小为1,这是为了区分不同实例化对象的地址。类大小的计算与结构体大小计算一样,需要考虑内存对齐。
一个类的大小只与非静态成员变量有关,类的内存模型是静态成员变量存放在全局区,非静态成员变量存放在对象内,静态和非静态成员函数存放在代码区。
4.this指针
this指针存在的目的是为了区分哪一个对象在调用成员函数从而操作它的成员变量。注意this指针是成员函数第一个隐藏形参,但是this指针是调用时才存在的才有意义,在对象调用成员函数时,会自动将对象地址传给第一个隐藏参数,即this指针指向了这个对象的地址,从而进行数据操作。
this指针是形参所以只能在成员函数内部使用,this指针本质是指针常量不能修改指向。常方法的const实际是加在了this指针前面,形成了常量指针常量。对象不存储this指针,对象只提供地址,传参过程也不需要程序员给出。this指针存在栈区,可以为空,代价是只能访问一般的成员函数,不能访问成员变量。
this指针的两个作用:1.区分形参和同名的成员变量。2.返回*this(对象本身),一般用于引用返回。
C语言类比实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
struct Person
{
char m_name[10];
int m_age;
};
void InitPerson(struct Person* const this,const char* name,int age)
{
strcpy(this->m_name, name);
this->m_age = age;
}
int main()
{
struct Person p;
InitPerson(&p, "张三", 18);
printf("姓名:%s, 年龄:%d", p.m_name, p.m_age);
system("pause");
return 0;
}
空指针情况:
#include<iostream>
using namespace std;
class Person
{
public:
void func1()
{
cout << "Person::func1()" << endl;
}
void func2()//空this指针无法访问
{
cout << m_age << endl;
}
private:
int m_age;
};
int main()
{
Person* p = nullptr;
p->func1();//正常执行
p->func2();//报错
system("pause");
return 0;
}