在变量前加const,说明变量是常量只读属性。假如用指针去修改const常量会用什么结果。上例子:ios
//a 是一个只读的常量,按照理论应该不能被修改 const int a = 10;//内存中为a分配地址,赋值 printf("sssss:&a:%d", &a); int *p = NULL; int *p2 = NULL; //当你对a取地址的时候,有一个内存空间(&a a的内存空间) p = (int *)&a;//此时取常量地址,同时将a值存在符号表中 printf("&a:%d p的值:%d", &a, p); *p = 11;//修改内存中值 printf("修改以后a:%d \n", a);//经过常量a(修饰符号表)而不是以前内存地址了。读取符号表中的值。 printf("*p:%d \n", *p);//读取内存中值,此时已经修改 printf("*p2:%d \n", *p2);//再次读取内存中,发现是11. system("pause");
在c++中const变量是只读的,当声明这个变量为常量的时候,这个变量不能修改。加入用指针获取地址,修改时,会数值分配到符号表,指针能够修改数值,可是变量a的值没有变化。
const和define区别
(1) 编译器处理方式不一样
define宏是在预处理阶段展开。
const常量是编译运行阶段使用。
(2) 类型和安全检查不一样
define宏没有类型,不作任何类型检查,仅仅是展开。
const常量有具体的类型,在编译阶段会执行类型检查。
(3) 存储方式不一样
define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
const常量会在内存中分配(能够是堆中也能够是栈中)。c++
(4)const 能够节省空间,避免没必要要的内存分配。 例如: 编程
#define PI 3.14159 //常量宏 const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 …… double i=Pi; //此时为Pi分配内存,之后再也不分配! double I=PI; //编译期间进行宏替换,分配内存 double j=Pi; //没有内存分配 double J=PI; //再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define同样给出的是当即数,因此,const定义的常量在程序运行过程当中只有一份拷贝,而 #define定义的常量在内存中有若干个拷贝。
(5) 提升了效率。 编译器一般不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操做,使得它的效率也很高。安全
const 与 #define的比较
C++ 语言能够用const来定义常量,也能够用 #define来定义常量。可是前者比后者有更多的优势:
(1) const常量有数据类型,而宏常量没有数据类型。编译器能够对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,而且在字符替换可能会产生意料不到的错误(边际效应)。
(2) 有些集成化的调试工具能够对const常量进行调试,可是不能对宏常量进行调试。markdown
l 【规则5-2-1】在C++ 程序中只使用const常量而不使用宏常量,即const常量彻底取代宏常量。ide
构造函数定义函数
拷贝构造函数工具
class Location { public: Location( int xx = 0 , int yy = 0 ) { X = xx ; Y = yy ; cout << "Constructor Object.\n" ; } Location( const Location & p ) //复制构造函数 { X = p.X ; Y = p.Y ; cout << "Copy_constructor called." << endl ; } ~Location() { cout << X << "," << Y << " Object destroyed." << endl ; } int GetX () { return X ; } int GetY () { return Y ; } private : int X , Y ; } ; void f ( Location p ) { cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl ; } // void playobjmain() // { // Location A ( 1, 2 ) ; // f ( A ) ; // } Location g() { Location A(1, 2);//构造函数调用第二次 return A;//一、(由于返回对象类型)编译器会自动建立一个临时对象调用构造函数,调用拷贝构造函数。 //二、由于须要返回,生命周期结束,对象A进行释放,调用析构函数 } void main101() { Location B;//构造函数调用一次 //开始进入被调用函数 B = g();//在赋值结束后,建立的临时对象须要销毁,调用了一次析构函数 } int main() { main101();//被调用函数结束了,第三次调用析构函数,析构对象B system("pause"); return 0; }
在c++中是面向对象编程,将变量(属性)和函数(方法)集中定义在一块儿,用于抽象描述现实世界的类。从计算机角度,程序依然由数据和代码段构成。那么从编译器角度如何完成面向对象理论到计算机程序的转化?也就是编译器如何管理类、对象、类和对象之间的关系。看一下代码:布局
#include "iostream" using namespace std; class C1 { public: int i; //4 int j; //4 int k; //4 protected: private: }; //变量很容易判断分配在内存中。 class C2 { public: int i; //4 int j; //4 int k; //4 static int m; //4 public: int getK() const { return k; } //4 void setK(int val) { k = val; } //4 protected: private: }; //从上面分析中函数会提供函数函数指针,理论上是每一个函数占用四个字节。若是这样的话,加入建立100多个对象,那内存不是占用不少,这样很不合理。同事变量是怎么处理的呢?实际内存大小是12,静态成员在全局区,属性整个类,不是对象。 struct S1 { int i; int j; int k; }; //12 struct S2 { int i; int j; int k; static int m; }; //16 int main() { printf("c1:%d \n", sizeof(C1)); printf("c2:%d \n", sizeof(C2)); printf("s1:%d \n", sizeof(S1)); printf("s2:%d \n", sizeof(S2)); system("pause"); }
那么用内存四区概念解析c++中属性和方法this