1.总结const 与指针的关系
如果const位于*的左侧,则const就是用来修饰指针指向的变量,即指针指向为常量;
int a=500; int const *p=&a; const int * p=&a;
*p=600;//err
改变*p的方法:
改变a的值
a=600
使p指向别处
p=&b;
如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量,必须进行初始化
int a=500; int* const p;//err,必须初始化 int* const p=&a; *p=600; p=&b;//err,不能修改指向
2.总结const 与引用的关系
const是为了不让修改,引用是为了避免复制
很多对象如果用传值,会复制一份,很占地方,用引用又怕函数修改它,所以用了常引用常引用
int main() { int a=10; int& b=a; const int& c=a;//常引用 a+=100; b+=100; //c+=100;err }
//不可能力扩展 int main() { const int a=10; //int& b=a;err a+=100;//err b+=100;//可,二义性,故不可int& b=a } //可能力收缩 int main() { int a=10; const int& x=a;//可 }
3.总结this指针
每个成员函数(包括构造函数和析构函数)都有一个this指针。this指针指向调用对象。如果方法需要引用整个调用对象,则可以用表达式* this。在函数的括号后面使用const限定符将this限定为const,这样将不能使用this来修改对象的值。然而,要返回的值并不是this,因为this是对象的指针,而是对象本身,即* this。
this指针只能在成员函数中使用,全局函数、静态函数都不能使用this
this在成员函数开始前构造,在成员的结束后清除。当调用一个类的成员函数时,编译器将类的指针作为函数的this参数传递进去
A a; a.func(10); 编译器编译为 A::func(&a,10);
this指针并不占用对象的空间。
this相当于非静态成员函数的一个隐函的参数,不占对象空间。它跟对象之间没有包含关系,只是当前调用函数的对象被它指向而已。所有成员函数的参数,不管是不是隐含的,都不会占用对象的空间,只会占用参数传递时的栈空间,或者直接占用一个寄存器。
thiscall调用约定:this指针存于ecx寄存器
a.fun();
move[this] ecx; lea ecx,[a];
__cdecl调用约定:
lea eax,[a]; push eax;
4. 设计矩形类。
class Rectangle
{
private:
int left, top, right, bottom;
public:
// 实现默认构造函数和带参的构造函数
Rectangle()
{
left = 0;
top = 0;
right = 0;
bottom = 0;
}
Rectangle(int l, int t, int r, int b)
{
left = l;
top = t;
right = r;
bottom = b;
}
// 实现Set函数
void SetLeft(int l);
void SetTop(int t);
void SetRight(int r);
void SetBottom(int b);
// 实现Get函数
int GetLeft();
int GetTop();
int GetRight();
int GetBottom();
void Show() const
{
cout << "left-top point is (" << left << "," << top << ")" << endl;
cout << "right-bottom point is (" << right << "," << bottom << ")" << endl;
}
};
void Rectangle::SetLeft(int l)
{
left = l;
}
void Rectangle::SetTop(int t)
{
top = t;
}
void Rectangle::SetRight(int r)
{
right = r;
}
void Rectangle::SetBottom(int b)
{
bottom = b;
}
int Rectangle::GetLeft()
{
return left;
}
int Rectangle::GetTop()
{
return top;
}
int Rectangle::GetRight()
{
return right;
}
int Rectangle::GetBottom()
{
return bottom;
}
int main()
{
Rectangle a;
a.Show();
a.SetLeft(1);
a.SetTop(2);
a.SetRight(3);
a.SetBottom(4);
cout << "left:" << a.GetLeft() << endl;
cout << "top:" << a.GetTop() << endl;
cout << "right:" << a.GetRight() << endl;
cout << "bottom:" << a.GetBottom() << endl;
Rectangle b(10, 20, 30, 40);
b.Show();
cout << "left:" << b.GetLeft() << endl;
cout << "top:" << b.GetTop() << endl;
cout << "right:" << b.GetRight() << endl;
cout << "bottom:" << b.GetBottom() << endl;
}
5.实现双向函数
class Object
{
private:
int value;
public:
Object(int x = 0) :value(x) {}
~Object() {}
void SetValue(int x) { value = x; }
int GetValue() { return value; }
// 使用一个函数实现 SetValue 和 GetValue() 函数的功能
int SetGet(int x)
{
value = x;
return value;
}
};
6 .实现Stack
#define SEQ_INIT_SIZE 10
#define SEQ_INC_SIZE 2
class SeqStack
{
private:
int* base;
int pos;//栈顶
int maxsize;
public:
SeqStack(int sz = SEQ_INIT_SIZE) :maxsize(sz > SEQ_INIT_SIZE ? sz : SEQ_INIT_SIZE)
{
base = (int*)malloc(sizeof(int) * maxsize);
pos = 0;
if (NULL == base) exit(1);
}
//实现函数有:
~SeqStack() // 析构函数
{
free(base);
base = NULL;
pos = 0;
maxsize = 0;
}
int Get_Size()// 返回数据的个数
{
return pos;
}
int Get_Capacity()// 返回容量
{
return maxsize;
}
bool Is_Empty()// 判空
{
return pos == 0;
}
bool Is_Full()// 判满
{
return pos == maxsize;
}
bool Push(int x) // 入栈
{
if (Is_Full())
return false;
base[pos++] = x;
return true;
}
bool Pop() // 出栈
{
if (Is_Empty())
return false;
pos--;
return true;
}
int Top() // 取栈顶数据 ,但不出栈
{
if (Is_Empty())
{
cout << "Stack Empty" << endl;
return -1;
}
return base[pos-1];
}
};
int main()
{
SeqStack s;
for (int i = 0; i < 10; i++)
{
s.Push(i);
cout << s.Top() << " ";
}
cout << endl;
for (int i = 0; i < 5; i++)
{
s.Pop();
cout << s.Top() << " ";
}
cout << endl;
cout << "size=" << s.Get_Size() << endl;
cout << "capacity=" << s.Get_Capacity() << endl;
}