zoukankan      html  css  js  c++  java
  • [类和对象]3 C++面向对象模型初探

    ? C++编译器如何完成面向对象理论到计算机程序的转化?

    [C++编译器是如何管理类、对象、类和对象之间的关系]

    通过下面的代码,我们可以的得出:
    C++类对象中的成员变量和成员函数是分开存储的

      成员变量:
        普通成员变量: 存储于对象中,与struct变量有相同的内存布局和字节对齐方式
        静态成员变量: 存储于全局数据区
        
      成员函数: 存储于代码段中。   

    #include "iostream"
    #include <cstdio>
    
    using namespace std;
    
    class C1
    {
    public:
        int i;  //4
     
        int j;  //4
     
        int k;  //4 
    protected:
    private:
    }; //12
    
    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:
    }; //12
    
    
    struct S1
    {
        int i;
        int j;
        int k;
    }; //
    
    struct S2
    {
        int i;
        int j;
        int k;
        static int m;
    }; //12
    
    int main(void)
     {
        cout<< sizeof(C1) << endl; //12
        cout<< sizeof(C2) << endl; //12
        cout<< sizeof(S1) << endl; //12
        cout<< sizeof(S2) << endl; //12
        
    return 0;
    }

    c1:12
    c2:12
    s1:12
    s2:12


    ? 很多对象共用一块代码?代码是如何区分具体对象的?  

    换句话说: int getK() const { return k; },代码是如何区分,具体obj1、 obj2、 obj3对象的k值?

    面向对象的过程依旧是建立在面向过程的基础上,

      比如创建了对象a,在初始化对象a的时候,就调用Tset_ininialize将a的地址[被隐藏封装]变量10传递给函数,

      如果调用函数getI()时候(对象a的数值I)时候,实际上仍然传递了对象a的地址

      同样的,其他对象也是如此这样做的好处,相比C极大的提高了代码的复用性

     

    C++普通成员函数都隐式包含一个指向当前对象的this指针,接受调用对象的地址, 静态成员函数不包含指向具体对象的指针,因为属于类的,所有对象公有的


    ?解释 int getK() const { return k; }, 


    全局函数和成员函数的转换

    #include <iostream>
    using namespace std;
    
    class Test
    {
    public://成员变量 
        int a;
        int b;
    
    public://构造函数 
        Test(int a = 0, int b = 0) //使用默认参数,就可以[偷懒]使用Test t3,而不加默认参数,则必须写为Test t3(1,2); 
        {
            cout<<"构造函数自动被调用
    "<<endl;
            this->a = a;
            this->b = b;
        }
        
        Test(const Test& obj)
        {
            cout<<"copy函数自动被调用
    "<<endl;
        }
        
        ~Test()
        {
            cout<<"析构函数
    "<<endl;
        }
    
    public://成员函数
        void printT()
        {
            cout<<"a:"<<a<<" b: "<<b<<endl;
        }
        
        //t3 = t1.TestAdd(t2);
        Test TestAdd(Test &t2)
        {
            Test tmp(this->a + t2.a, this->b + t2.b);
            return tmp;
        }
    
        //t1.TestAdd2(t2); 目的是把 t1 = t1 + t2 
        //返回一个引用 相当于 返回自身 
        //返回t1这个元素 this就是&t1
        Test& TestAdd2(Test &t2)
        {
            this->a = this->a + t2.a;
            this->b = this->b + t2.b;
            
            return *this; //把 *(&t1) 又回到了 t1元素
        }
    };
    
    /*____________把成员函数 转成 全局函数 多了一个参数____________*/
    
    void printT(Test *pT)
    {
        cout<<"成员函数 2 全局函数
    "<<endl;    
        cout<<"a:"<<pT->a<<" b: "<<pT->b<<endl;
    }
    
    
    Test TestAdd(Test &t1, Test &t2)
    {
        Test tmp;
        tmp.a = t1.a + t2.a;
        tmp.b = t1.b + t1.b;
        cout<<"全局函数  2  成员函数
    "<<endl;
        return tmp;
    }
    /*________全局函数 转成 成员函数  少了一个参数______________*/
    
    
    int main(void)
    {
        Test t1(1, 2);
        Test t2(3, 4);
    
        //全局函数方法
    //    Test t3;
    //    t3 = TestAdd(t1, t2);
    //    t3.printT();
        
        //成员函数方法  //先把测试案例写出来
        {
    //        接收匿名对象方法1 
            Test t4 = t1.TestAdd(t2); //匿名对象直接转化成t4
            t4.printT();
            
            //接收匿名对象方法2
            Test t5;
            t5 = t1.TestAdd(t2); //匿名对象 赋值 给t5
            t5.printT();
        }
        
        //返回引用
        t1.TestAdd2(t2);
        t1.printT(); 
    
        return 0;
    }

    数组类封装 

    main.cpp 

    #include <iostream>
    #include "MyArray.h"
    
    using namespace std;
     
    int main(int argc, char** argv) {
        Array a1(10);
        
        for(int i = 0; i < 10; i++) {
            a1.setData(i, i);        
        }
        cout<<"printf a1
    ";    
        for(int i = 0; i < a1.length(); i++) {
            cout<< "a1.getData:"<<a1.getData(i) <<endl; 
        }
        
        cout<<"printf a2
    ";    
        Array a2 = a1;
        for(int i = 0; i < a2.length(); i++) {
            cout<< "a2.getData:"<<a2.getData(i) <<endl; 
        }
        
         
        cout << "Hello world!
    ";
        return 0;
    }

    myarray.cpp

    #include "MyArray.h"
    //int m_length;
    //int *m_space;
    Array::Array(int length)
    {
        if (length < 0)
        {
            length = 0; //
        }
    
        m_length = length;
        m_space = new int[m_length];
    }
    
    //Array a2 = a1;
    Array::Array(const Array& obj)
    {
        this->m_length = obj.m_length;
        this->m_space = new int[this->m_length]; //分配内存空间
    
        for (int i=0; i<m_length; i++) //数组元素复制
        {
            this->m_space[i] = obj.m_space[i];
        }
    }
    
    Array::~Array()
    {
        if (m_space != NULL)
        {
            delete[] m_space;
            m_space = NULL;
            m_length = -1;
        }
    }
    
    //a1.setData(i, i);
    void Array::setData(int index, int valude)
    {
        m_space[index] = valude;
    }
    
    int Array::getData(int index)
    {
        return m_space[index];
    }
    
    int Array::length()
    {
        return m_length;
    }

    myarray.h

    #pragma  once
    
    #include <iostream>
    using namespace std;
    
    class Array
    {
    public:
        Array(int length);
        Array(const Array& obj);
        ~Array();
    
    public:
        void setData(int index, int valude);
        int getData(int index);
        int length();
    
    private:
        int m_length;
        int *m_space;
    };
    
    //要求重载以下操作符
    // []  ==  !=  
  • 相关阅读:
    Scala编译环境搭建(mac IDEA)
    Scala初见
    boost spirit使用
    基于OPENCV的图像融合
    C++获取hostname&IP&MAC地址
    httpd启动检查
    react eslint 代码格式补全的插件
    将html页面导出为word
    redux的笔记
    img onerror事件的使用
  • 原文地址:https://www.cnblogs.com/-Mr-y/p/7804405.html
Copyright © 2011-2022 走看看