zoukankan      html  css  js  c++  java
  • c++重点知识点

    - const加强

    在变量前加const,说明变量是常量只读属性。假如用指针去修改const常量会用什么结果。上例子:

    //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 
    ", a);//通过常量a(修饰符号表)而不是之前内存地址了。读取符号表中的值。
        printf("*p:%d 
    ", *p);//读取内存中值,此时已经修改
        printf("*p2:%d 
    ", *p2);//再次读取内存中,发现是11.
        system("pause");
    View Code

    这里写图片描述
    在c++中const变量是只读的,当声明这个变量为常量的时候,这个变量不能修改。加入用指针获取地址,修改时,会数值分配到符号表,指针可以修改数值,但是变量a的值没有变化。
    const和define区别
    (1) 编译器处理方式不同
      define宏是在预处理阶段展开。
      const常量是编译运行阶段使用。
    (2) 类型和安全检查不同
      define宏没有类型,不做任何类型检查,仅仅是展开。
      const常量有具体的类型,在编译阶段会执行类型检查。
    (3) 存储方式不同
      define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
      const常量会在内存中分配(可以是堆中也可以是栈中)。

    (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; //再进行宏替换,又一次分配内存! 
    View Code


    const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而 #define定义的常量在内存中有若干个拷贝。
    (5) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

    const 与 #define的比较
    C++ 语言可以用const来定义常量,也可以用 #define来定义常量。但是前者比后者有更多的优点:
    (1) const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。
    (2) 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

    l 【规则5-2-1】在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。

    - 构造函数

    • 构造函数定义

      1. 在c++中有三种构造函数,构造函数是c++中用于初始化对象初始状态的特殊函数。
      2. 构造函数在对象创建是自动调用,隐身调用。
      3. 构造函数和普通成员构造函数遵循重载规则
      4. 拷贝构造函数是对象正确初始化的重要保证。
      5. 析构函数在对象周期结束时调用。
    • 拷贝构造函数

      1. 拷贝构造函数也是构造函数,用来构造对象。
      2. 拷贝构造函数和=是两个不同概念
      3. 当我们没有编写拷贝构造函数的时候便一起你会默认提供copy构造函数,执行的是浅拷贝。(test t= t2;)
      4. 函数返回 类类型是,通过复制构造函数建立临时对象。
    class Location
    {
    public:
        Location( int xx = 0 , int yy = 0 )
        {
            X = xx ;  Y = yy ;  cout << "Constructor Object.
    " ;
        }
        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;//1、(因为返回对象类型)编译器会自动创建一个临时对象调用构造函数,调用拷贝构造函数。
        //2、因为需要返回,生命周期结束,对象A进行释放,调用析构函数
    }
    void main101()
    {
        Location B;//构造函数调用一次
        //开始进入被调用函数
        B = g();//在赋值结束后,创建的临时对象需要销毁,调用了一次析构函数
    
    }
    
    int main()
    {
        main101();//被调用函数结束了,第三次调用析构函数,析构对象B
        system("pause");
        return 0;
    }
    View Code

    内存角度分析类

    在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 
    ", sizeof(C1));
        printf("c2:%d 
    ", sizeof(C2));
        printf("s1:%d 
    ", sizeof(S1));
        printf("s2:%d 
    ", sizeof(S2));
    
        system("pause");
    }
    View Code

    那么用内存四区概念解析c++中属性和方法

    • c++类对象中成员变量和成员函数时分开存储的。
      • 成员变量:
        • 普通成员变量:存储在对象中,与struct变量有相同的内存布局和字节对齐方式
        • 静态成员变量:存储与全局数据区。
      • 成员函数:存储于代码段中。
        很多对象公用一块代码段,代码是怎么如何区分具体对象?其实在c++中类普通成员函数都隐式包含一个指向当前对象的this指针。
        静态成员函数是属于整个类的额,所以没有隐式的this指针。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    买房的贷款时间是否是越长越好?https://www.zhihu.com/question/20842791
    asp.net cookie and session
    leelazero and google colab
    download file by python in google colab
    physical processor, core, logical processor
    通过powershell操作eventlog
    openxml in sql server
    get the page name from url
    How to Execute Page_Load() in Page's Base Class?
    Difference between HttpContext.Request and Request
  • 原文地址:https://www.cnblogs.com/polly333/p/4705667.html
Copyright © 2011-2022 走看看