• 剑指Offer读书笔记(持续更新中)


    (1)定义一个空的类型,里面没有不论什么成员变量和成员函数,对该类型求sizeof,得到的结果是多少?

    答案是1。空类型的实例中不包括不论什么信息,本来求sizeof应该是0,可是当我们声明该类型实例的时候,它必须在内存中占有一定的空间,否则无法使用这些实例。

    至于占用多少内存。由编译器决定。

    Visual Studio中每一个空类型的实例占用1字节的空间。


    假设在该类型中加入一个构造函数和析构函数,再对该类型求sizeof,得到的结果又是多少?

    答案还是1。调用构造函数和析构函数仅仅须要知道函数的地址就可以,而这些函数的地址仅仅与类型相关。而与类型的实例无关,编译器也不会由于这两个函数而在实例内加入不论什么额外的信息。


    假设把上述的析构函数标记为虚函数,情况会如何?

    C++编译器一旦发现一个类型中有虚函数,就会为该类型生成虚函数表,并在该类型的每个实例中加入一个指向虚函数表的指针,在32位的机器上,一个指针占4字节的空间。因此求sizeof得到4,假设是64位的机器,一个指针占8字节的空间。因此求sizeof得到8.


    (2)看C++程序,推断结果:

    #include <iostream>
    
    class A{
    
    private:
        int value;
        
    public:
        A(int n){
        
            value = n;
        }
        
        A(A other){
        
            value = other.value;
        }
        
        void Print(){
        
            std::cout<<value<<std::endl;
        }
    };
    
    int main(int argc, const char * argv[]) {
    
        A a = 10;
        A b = a;
        b.Print();
        
        return 0;
    }
    

    选择A.编译错误       B.编译成功,执行时程序崩溃             C.编译执行正常。输出10


    答案是A。编译出错。

    我把程序放到IDE中,报错行数和提演示样例如以下:

    错误提示是说复制构造函数传递的第一个參数必须是引用类型。

    在上述代码中,复制构造函数A(A other)传入的參数是A的一个实例。因为是传值參数,我们把形參拷贝到实參会调用复制构造函数。因此假设同意复制构造函数传值,就会在复制构造函数内调用复制构造函数,就会形成永无休止恶递归调用从而导致栈溢出。因此C++标准不同意复制构造函数传值參数。

    在Visual Studio和GCC中,都会编译出错。要解决问题,就是把传值參数改动为常量引用。

    代码例如以下:

    A(A const &other){
        
            value = other.value;
        }

    (3)题目:例如以下为类型CMyString的声明,请为该类型加入赋值运算符函数。

    class CMyString{
    
    public:
        CMyString(char* pData = NUll);
        CMyString(const CMyString& str);
        ~CMyString(void);
        
    private:
        char* m_pData;
    
        
    };

    解决该问题应该首先注意下面几点:

             1.是否把返回值的类型声明为该类型的引用。并在函数结束前返回实例自身的引用(即*this)。

    仅仅有返回一个引用,才干够同意连续赋值。否则如果函数的返回值是void,应用该赋值对象符将不能做连续赋值。如果有三个CMyString对象,str1,str2,str3,在程序中语句str1=str2=str3将不能通过编译。

            2.是否把传入的參数的类型声明为常量引用。假设传入的參数不是引用而是实例,那么从形參到实參会调用一次复制构造函数。把參数声明为引用能够避免这种无谓的消耗,能提高代码的效率。同一时候,我们在赋值运算符函数内不会改变传入的实例的状态。因此应该为传入的引用參数加上constkeyword。

            3.是否释放实例自身已有的内存。假设我们忘记在分配新内存之前释放自身已有的空间,程序将出现内存泄露。

            4.是否推断传入的參数和当前的实例(*this)是不是同一个实例。假设是同一个,则不进行赋值操作,直接返回。假设事先不推断就进行赋值,那么在释放实例自身的内存的时候就会导致严重的问题:当*this和传入的參数是同一个实例时,那么一旦释放了自身的内存。传入的參数的内存也同一时候被释放了,因此再也找不到须要赋值的内容了。


    实现代码例如以下:

    CMyString& CMyString::operator = (const CMyString &str){
    
      if(this == &str){
      
        return *this;
        
      }
      
      delete []m_pData;
      m_pData = NULL;
      m_pData = new char[strlen(str.m_pData) + 1];
      strcpy(m_pData,str.m_pData);
      
      return *this;
    }
    

    (4)C++中能够使用struct和class来定义类型,这两种类型有什么差别?

    假设没有标明成员函数或者成员变量的訪问权限级别,在struct中默认是public,在class中默认是private。



    github主页:https://github.com/chenyufeng1991  。

    欢迎大家訪问。












  • 相关阅读:
    python常用运维脚本实例
    数据库优化方案整理
    Python第一章概述与环境安装
    九阴真经
    常用的kubectl命令
    第7篇管理存储资源
    第8篇NFS PersistentVolume
    第10篇用 ConfigMap 管理配置
    第11篇Kubernetes部署微服务电商平台
    第12篇Kubernetes 监控
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7097288.html
Copyright © 2020-2023  润新知