一:
1.普通成员变量 VS 静态成员变量
2.普通成员方法 VS 静态成员方法
class counter
{
public:
counter():cou(0)
{
num++;
cou++;
}
//_thiscall,调用依赖对象 默认有counter *const this
void showcou()
{
cout << cou << endl;
}
//_cdecl,调用依赖类的作用域,没有this指针
static void shownum()
{
cout << num << endl;
}
private:
int cou;
static int num; //记录产生对象数量,存储在数据段上
};
//静态成员变量不属于对象的内存,和对象没关系
//所以不在对象内初始化,而是在类外
//类外初始化时需要加类的作用域
int counter::num = 0;
int main()
{
counter c1;
counter c2;
counter c3;
counter::shownum();
c3.showcou();
return 0;
}
结论:
1.普通成员变量 VS 静态成员变量:
普通的成员变量:
是对象的内存的一部分,访问或者使用的时候必须依赖于对象;
初始化要在构造函数中初始化。
静态成员变量:
属于数据段.data段数据,不属于对象的内存,是所有对象共有的数据,访问时只需要依赖类的作用域即可,所以普通成员方法也可以访问;
初始化时在类外初始化,而不是构造函数,因为作用域是属于类的。
2.普通成员方法 VS 静态成员方法:
普通成员方法:
属于对象的属性,所以调用时必须依赖于对象;
含有this指针,所以可以访问对象的成员变量,包括属于静态变量,但是一般不这样用,一般都是通过静态方法访问静态变量;
肯定是属于类的作用域。
静态成员方法:
属于类作用域下的方法;
不能访问对象的私有属性,因为没有this指针,只能访问除对象私有的变量,一般是静态变量,只能访问不依赖对象的一些东西。
class counter
{
public:
counter():cou(0)
{
num++;
cou++;
}
//_thiscall,调用依赖对象 this指针类型为counter *const this
void showcou()
{
cout << "void showcou()" << endl;
cout << cou << endl;
}
//产生的this指针const counter *const this ,与上面show构成重载
//常方法的定义方式,参数列表后加const
void showcou()const
{
cout << "void showcou()const" << endl;
cout << cou << endl;
}
static void shownum()
{
cout << num << endl;
}
private:
int cou;
static int num;
};
int counter::num = 0;
int main()
{
counter c1;
counter c2;
const counter c3; // &c3 const counter *
c3.showcou(); //counter *const this
return 0;
}
二:
1.常量对象VS普通对象
&常量对象------> const counter *const this
&普通对象------>counter *const this
本质区别是当对象去调用成员方法时,自己产生的地址类型如上,能否去初始化形参默认的类型,决定了能不能调用方法;
如:
用const counter *const this 去初始化形参counter *const this,FALSE
(实际上用常对象调用普通方法,常对象肯定不允许修改啊)
用counter *const this去初始化形参const counter *const this,TRUE
(实际上用普通对象调用常方法)
用counter *const this去初始化形参counter *const this,TRUE
(实际上就是普通对象调用普通的方法啦)
用const counter *const this 去初始化形参const counter *const this ,TRUE
(实际上就是常对象调用常方法)
2.常量方法VS普通方法
根本区别是产生的this指针的类型不同,也就是对象地址的类型和形参的类型来判断匹配。
常方法一般用简单的访问成员变量,不做修改;
普通方法当然既可以修改也可以访问了。
普通方法可以调用常方法,
常方法不可以调用普通方法,常方法只能调用常方法。
原因:也是和this指针的类型匹配和能否转化有关。
三、
常方法、普通方法、静态方法
常方法、普通方法都可以调用静态方法,因为常方法、普通方法都是类作用域下的;
普通方法可以调用常方法;
静态方法中不能调用普通方法、常方法、普通成员变量,因为没有this指针。
class test
{
public:
test(int val) :mvalue(val){}
int getvalue(){ return mvalue; }//test*const this
int getvalue()const{ return mvalue; }//const test*const this
private:
int mvalue;
};
int main()
{
test t(20);
int a = t.getvalue();
//int &b = t.getvalue();
//寄存器带回的常量,所以要常引用,会产生临时量
const int &b = t.getvalue();
const int &c = t.getvalue();
test t1(100);
int a1 = t1.getvalue();
const int &b1 = t1.getvalue();
const int &c1 = t1.getvalue();
return 0;
}
四、返回值怎么带回
c语言中返回值无论时内置类型还是struct等自定义类型,返回值遵循以下规律:
1.返回值小于等于四字节,通过一个寄存器带回;
2.返回值大于四字节小于等于八字节,通过两个寄存器带回;
3.返回值大于八字节,返回值通过产生临时量带回。
返回值不论内置还是自定义,都遵循以上规律。
在c++中,只要返回对象,一般都要产生临时量。