一、对象和成员的存储
- 系统会给每一个定义了的空对象分配1字节的内存空间,为了标志出改对象在内存中的位置,要是该对象有了一个非静态成员变量,则这个对象的内存为他的非静态成员变量之和。
- 静态成员变量和静态成员函数都不在对象上,因为他们是共享的函数,所以不会储存到某个特定的对象的内存里。
- 非静态成员函数也不在其对象上。
二、this指针
- this指针可以解决成员变量和形参的命名相同时的冲突
哪个对象调用方法,该方法中就会产生一个this指针指向这个对象。this指针是隐含在对象成员函数内的一种指针
成员函数通过this指针即可知道操作的是那个对象的数据
静态成员函数内部没有this指针,静态成员函数不能操作非静态成员变量(静态成员函数 是属于类 函数内部 没有this指针)
2、在类的普通成员函数中返回对象本身(*this)
#include <iostream>
#include <string>
using namespace std;
class student {
public:
string sentence;
student &say(string sentence)
{
this->sentence = sentence;
cout<<sentence;
return *this;
}
};
void test1()
{
student stu_1;
stu_1.say("我").say("爱").say("C++");
}
int main()
{
test1();
system("pause");
}
注意:这里的函数名student &say
,必须加一个&指向引用这个函数的本体,否则后面链式编程的时候,相当于每次都重新执行拷贝构造函数,导致原先那个对象只执行了一次函数。
#include <iostream>
#include <string>
using namespace std;
class student {
public:
string sentence;
student say(string sentence)
{
this->sentence = sentence;
return *this;
}
};
void test1()
{
student stu_1;
stu_1.say("我").say("爱").say("C++");
cout<<stu_1.sentence<<endl;
}
int main()
{
test1();
system("pause");
}
三、使用空指针调用成员函数
如果定义了一个类型为某个类的空指针对象,这个时候如果再用这个对象的this指针就会报错,因为此时空指针指向的地址不能被访问。
#include <iostream>
#include <string>
using namespace std;
class student {
public:
void display1() //这里没有this指针,不会报错
{
cout<<"不带成员变量的display1被空指针调用了"<<endl;
}
void display2() //这里用了this指针,会报错
{
cout<<this->age<<endl;
cout<<"带有成员变量的display2被空指针调用了"<<endl;
}
int age;
};
void test1()
{
student *p=NULL;
p->display1();
p->display2();
}
int main()
{
test1();
system("pause");
}
四、利用const修饰成员函数
-
this指针的本质时指针常量,指针的指向是不可更改的。
-
在成员函数后面加const,修饰的是this的指向,让指针指向的值也不可以修改。
-
定义成员变量时加上mutable,则该即使使用const修饰了this指针,该变量也可被修改
-
常对象的成员变量不能被修改,否则与其常对象的定义相悖
-
常对象只能调用常函数,不能调用非常函数
#include <iostream>
#include <string>
using namespace std;
class student {
public:
int age;
void display_1() const //相当于const Student *const this
{
this->age=18;
this->num=10;
}
void display_2()
{
cout<<"常对象只能调用常函数"<<endl;
}
mutable int num;
};
void test1()
{
const student stu_1;
stu_1.age=10; //常对象的值不允许被修改
stu_1.display_1(); //常对象只能调用常函数
stu_1.display_2(); //常对象不能调用非常函数
}
int main()
{
test1();
system("pause");
}