• Questions Per Chapter


    第2章:开始学习C++

    1.源代码生成可执行代码的过程?
    2.编译指令usingusing namepace有何区别?
    3.coutcin对应于C中的什么函数,要包含哪个头文件?
    4.endl\n有何区别?
    5.main()函数返回的值是什么含义?是返回给程序其他部分还是操作系统?

    第3章:处理数据

    1.通过cout输出十进制、十六进制和八进制,分别用什么控制符
    2.程序将把1492存储为intlong还是其他整型呢?
    3.有原型:ostream& cout.put(char c);那么cout.put('$');cout << '$';有区别吗?
    4.什么是通用字符名?它的用法类似于?通用字符名的表示有哪两种前缀,含义有何不同?后缀表示的那些位是字符的哪个国际标准的码点?例如:ö的国际标准码点为00F6,â的码点为00E2。请➀定义一个变量名为körper的整型变量;➁直接输出字符串:gâteau。
    5.ASCIIUnicodeISO 10646之间的关系?通用字符集(Universal Character Set, UCS)是由ISO制定的哪个标准所定义的标准字符集?
    6.扩展字符集用哪个类型来表示?它具体是一个什么类型?8位char不够用所以用扩展字符集吗?它在系统底层表示是unsigned short还是int或者是其他类型呢?cincout能直接用在这种宽字符类型吗?宽字符常量和宽字符串,怎么表示?在支持两字节wchar_t的系统中,将会把每个字符存储在一个几字节的内存单元中?
    7.char16_tchar32_t表示的是意思分别是?它们分别使用什么前缀去表示字符常量和字符串?与wchar_t一样,它们也都有什么底层类型?
    8.bool类型的字面量truefalse都可以通过提升转换为int类型吗?可以int ans = true;这样吗?ans等于什么?同样,可以bool start = -100;这样吗?start等于什么?
    9.为什么C++提倡使用const代替#define
    10.整型常量和浮点常量的默认类型分别是?
    11.static_cast(value)是什么作用?相比C的强转,它有何优点?
    12.auto关键字的作用是什么?如下代码中n、x、y分别是什么类型?

    auto n = 100;
    auto x = 1.5;
    auto y = 1.3e12L;
    
    • 1
    • 2
    • 3

    第4章:复合类型

    1.如下代码打印出什么?为什么?

    int i = 3;
    int* p = &i;
    char dog[8] = {'b', 'e', 'a', 'u', 'x', ' ', 'I', 'I'};
    char cat[8] = {'f', 'a', 't', 'e', 's', 's', 'a', '\0'};
    cout << p;
    cout << dog;
    cout << cat;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.如下代码运行,对应的输入,最终打印的结果有什么问题吗?为什么?
    代码中cin读取单词后将字符串放到数组中,会自动在结尾添加空字符吗?

    int main() {
    	char name[20];
        char dessert[20];
    	cout << "Enter your name:\n";
    	cin >> name;
        cout << "Enter your favorite dessert:\n";
        cin >> dessert;
        cout << "I have some delicious " << dessert << " for you, " << name << ".\n";
       	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    Enter your name:
    |Alistair Dreeb
    Enter your favorite dessert:
    I have some delicious Dreeb for you, Alistair.
    
    • 1
    • 2
    • 3
    • 4

    3.以上代码的问题,如何用其他函数来解决?
    4.原始(raw)字符串,含义是?格式上来说,前缀是?定界符是?如果字符串中包含定界符,那又该用什么格式呢?如果字符串是wchar_t等类型又该是什么格式呢?
    5.什么叫静态联编(static binding)?什么叫动态联编(dynamic binding)
    6.使用数组名或指针时,C++都将执行下面的转换,为什么?arr[-2]代表什么意思?

    arrayname[i] => *(arrayname + i)
    pointername[i] => *(pointername + i)
    
    • 1
    • 2

    7.自动存储、静态存储和动态存储的含义与区别?栈、堆的含义与区别?
    8.使变量成为静态有哪两种方式?
    9.指针数组是什么意思?声明一个指向指针数组的变量,应该是一个指针的指针吗?指针与指针的指针有何关键区别?
    10.模板类vectorarray,从功能、底层机制、特点、安全和效率这几个方面对比一下?

    第5章:循环和关系表达式

    1.下面代码输出什么?为什么?如果要像预想的那样工作,该怎么做?

    char word[] = "mate";
    bool b = word == "mate";
    cout << b;
    
    • 1
    • 2
    • 3

    2.获取时间用哪个函数?要包含哪个头文件?如何得到系统时间的秒数?
    3.我们知道cin和scanf一样使用空白(空格、制表符和换行符)来确定字符串的结束位置,如果要读取单个空白符,应该用哪个函数呢?
    4.EOF是什么含义?它在源代码中是被怎么定义的?在一个循环读取字符的代码中,如何模拟EOF?此时while循环的条件应该是什么?
    5.while(cin)while(cin.good())while(!cin.fail())while(!cin.eof())while(!cin.bad()),它们有何异同?哪个更通用?

    第6章:分支语句和逻辑运算符

    1.要判断一个字符是否是字母、空格、数字、标点符号、大小写、控制符…,用哪个函数库?
    2.cin.clear()函数的作用机制是什么?如何用它帮助完成输入类型不匹配时给出提示(输入只能是数字而不能是其他字符)?
    3.去除输入缓存一般用哪句while循环?
    4.C++为标准输入和输出定义了一些格式标志,可通过哪三个函数来控制?
    5.写入到文本文件中,一般有哪四个步骤?
    6.检测IO错误时,good()fail()eof()bad()它们各有何特点?

    第7章:函数——C++的编程模块

    1.为何编译器需要函数原型?
    2.下图说明了传参的什么特点?
    ​​
    3.对于形参func(int arr[])这里arr实际是:数组or指针?如果将形参改为int* arr可以吗?
    4.在形参有何特点时,会用const修饰?目的是?
    5.对于一个二维数组arr[r][c],总有恒等式arr==&arr[0]吗?怎么用指针表示法来表示这个二维数组?
    6.函数也有指针,那么函数的地址是在哪呢?
    7.首先着重理解typedef的妙用,问:下面代码的最后一行代码中的pd代表的意思是?

    typedef const double* (*p_fun)(const double*, int);
    p_fun pa[3] = { f1,f2,f3 };// f1,f2,f3是函数名
    p_fun (*pd)[3] = &pa;
    const double* (*(*pd)[3])(const double *, int) = &pa;
    
    • 1
    • 2
    • 3
    • 4

    第8章:函数探幽

    1.简单描述下函数的调用过程?为什么需要内联函数?为什么提倡用内联函数替换宏定义?
    2.为什么说引用看上去很像伪装表示的指针?
    3.怎么理解如下代码?引用有什么特点?

    int & rodents = rats;
    实际上是下述代码的伪装表示:
    int * const pr = &rats;// 指针常量
    
    • 1
    • 2
    • 3

    4.下图说明了什么?

    5.下面代码打印输出什么?

    #include 
    using namespace std;
    int main() {
    	int x = 6;
    	int& y = x;
    	int& z = y;
    	y = 9;
    	cout << x << "," << y << "," << z << endl;
    	z = 10;
    	cout << x << "," << y << "," << z << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6.为什么有时函数要返回引用?返回引用实际上返回的是什么?返回引用一定要注意什么?
    7.什么情况下最好将返回类型声明为const引用?
    8.如下代码是什么作用?要包含哪个头文件?

    cout << numeric_limits<string::size_type>::max() << endl;
    
    • 1

    9.何时使用引用参数、何时使用指针参数、何时使用按值传递?
    10.要设置函数默认值,是要在函数体对应的形参上标明吗?还是说必须得怎样?
    11.要为某个参数设置默认值,则必须为它右边的所有参数都提供默认值吗?为什么?
    12.使用默认参数,可以减少哪三方面函数的数量?
    13.函数模板即是使用泛型来定义函数,那么定义一个函数模板需要在函数体顶部怎么声明?用到哪些关键字?
    14.如果函数模板中的类型是个结构体,现要交换结构体的成员,用普通模板函数可以完成吗?如果不能那应该用哪种格式/类型的模板?
    15.显式具体化的原型和定义应以什么打头、并通过名称来指出类型?
    16.看下面代码,代码中变量xpy是什么类型?怎么解决这种情况?

    template<class T1, class T2>
    void ft(T1 x, T2 y) {
        ?type? xpy = x + y;
    }
    
    • 1
    • 2
    • 3
    • 4

    17.下面代码的返回类型怎么解决(注意要用到两个关键字,同时用到后置返回类型)?

    template<class T1, class T2>
    ?type? gt(T1 x, T2 y) 
    {
        return x + y;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第9章:内存模型和名称空间

    1.为什么要在头文件里面定义#ifndef XXX_H #define XXX_H ..... #endif
    2.cin可以连续获取值吗?比如cin >> screen.x >> screen.y,为什么?
    3.下图表达出什么思想(理解图左侧栏1、2、3、4步骤)?

    4.“静态”这个词只是说明具有外部链接性。C++为静态存储持续性变量提供了3种链接性,是哪3种?各有什么特点?
    5.所有的静态持续变量都有的初始化特征是:未被初始化的静态变量的所有位都被设置为什么值?
    6.有4种变量的存储方式,下图很好的总结了,能用自己的话简短再描述一下这4种存储方式吗?

    7.C++有“单定义规则”,即变量只能有一次定义,为此,有两种变量声明,一种是定义声明,另一种是引用声明。
    那么,引用声明要用哪个关键字,怎么使用?关键字用在哪个文件里?请结合下面代码示例,“在引用变量的同时对它进行赋值会破解引用而成为了定义变量”,这话怎么讲?可以在引用之后再更改引用变量的值吗?

    // file1.cpp
    int cats = 10;
    // main.cpp
    #include
    extern int cats = 20;// Error!去掉赋值“=20”一切OK! 
    /* 注:赋值后就会为变量分配空间,这就成为了变量定义,就不属于单纯的引用了!*/
    int main() {
    	cats = 30;
    	std::cout << cats;// 解决掉Error后,就能正常输出:30
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行报错:(Error message:“already defined”直观地表明“main.cpp”中引用的变量cats被赋值后就成为变量的定义了)

    8.如果一个文件中有全局变量,在一个函数体里也有局部的同名变量,该如何在函数体里访问全局的同名变量呢?
    9.下面代码运行会报错吗?它违反了什么规则?

    // file1
    int errors = 20;
    ----------------------------
    // file2
    int errors = 5;
    void froobish() {
        cout << errors;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    10.在.cpp文件中全局声明一个const修饰的变量,是“静态,外部链接性”吗?
    11.下面代码的上半部分说明了什么问题?是什么原因导致的?代码的下半部分没任何问题,说明了#include的什么本质?

    // file1.cpp
    const int x = 10;// 放在.cpp文件。链接性:静态,内部
    -----------------
    // file2.cpp
    extern const int x;// 运行后此行报错:unresolved external symbol "int const x"
    /* 去掉file1.cpp与file2.cpp中的const,就正常了 */
    int main() {
        cout << x;
    }
    ############## 上半部分↑↑,下半部分↓↓ ##############
    // dolly.h
    static int x = 10;// 放在头文件,静态内部链接
    const int y = 20; // 放在头文件,静态内部链接
    // filey.cpp
    #include "dolly.h"// 包含头文件
    int main() {
    	/* 直接【拥有】了头文件的内容,使成为本文件的作用域了!
    	   如果要多此一举,去引用头文件的变量,也是没问题的。*/
        cout << x << "," << y; // 正常输出:10,20
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    12.默认函数是什么链接性?加上static关键字后呢?
    13.如果要[ 在C++程序中使用C库中预编译的函数 ],将出现什么问题呢?
    对于下面第一行代码,假设函数名在C翻译为_spiff,而在C++翻译为_spiff_i,extern "C/C++"必须放置在函数原型吗?它是怎么解决了问题的?

    extern "C" void spiff(int);
    extern "C++" void spaff(int);// 可缺省前缀,因是C++默认行为
    
    • 1
    • 2

    14.如果new找不到请求的内存量,会发生什么?
    15.如果想把一个数组或结构放到一个已分配内存的区域,可以用哪种方法?需要包含哪个头文件?
    16.使用定位new运算符后,如下面的代码,返回的指针p2、p4该怎么使用?需要配套使用delete吗?为什么?

    #include 
    struct chaff { char dross[20]; int slag; };
    char buffer1[50];
    char buffer2[500];
    int main() {
        chaff *p1, *p2;
        int *p3, *p4;
        p1 = new chaff; // 把结构放进堆中
        p3 = new int[20]; // 把int数组放进堆中
        // 两种形式的new替换
        p2 = new (buffer1) chaff; // 把结构放进buffer1
        p4 = new (buffer2) int[20]; // 把int数组放进buffer2
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    17.书上讲到:“在默认情况下,在名称空间中声明的名称的链接性为外部(除非它引用了const常量)。”,怎么理解这句话?下面的示例揭示出的事实怎么与书上讲的是矛盾的呢?结合下面示例,最终能得出什么其他的结论呢?

    // my.h
    #pragma once
    namespace myspace {
    	int age;
    }
    // file.cpp
    namespace myspaceT {
    	int ageT;
    }
    // main.cpp
    #include
    #include "my.h"
    int main() {
    	std::cout << myspace::age;// OK
    	auto a = myspaceT;// undefined!
    	auto b = ageT;// undefined!
    	auto c = myspaceT::ageT;// no class!no namespace!
    	/* 如果file.cpp中自定义的名称空间默认链接性是“外部”,
    	 * 那main.cpp怎么不能直接访问到呢?根本识别不到那个名称空间的一切。
    	 */
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21


    18.using声明和using编译指令有何区别?它们存在的作用是什么?
    19.下面代码输出什么?

    #include
    namespace Jill {
    	double fetch;
    }
    double fetch;
    int main() {
    	std::cout << &fetch << std::endl;
    	using Jill::fetch;// using声明!将fetch放入【局部名称空间】main(){}块作用域
    	std::cin >> fetch;// 读取一个值到Jill::fetch
    	std::cin >> ::fetch;// 读取一个值到全局fetch
    	std::cout << fetch << "|" << ::fetch << std::endl;
    	std::cout << &fetch << "|" << &(::fetch);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    20.下面代码,第一行是什么?直观意思是?第二行是什么?直观意思又是什么?

    using std::cout;
    using namespace std;
    
    • 1
    • 2

    21.为什么不提倡不分青红皂白地使用using编译指令?举例子说明。
    22.未命名名称空间的链接性为?有什么特别的作用?
    23.说说名称空间对编程设计蓝图带来的作用?

    第10章:对象和类

    1.下面代码,直接在类声明外定义私有成员函数,可行吗?为什么?
    默认在类中直接给出定义的函数都是什么函数?

    // stock.h
    class Stock {
    	private:
    		long shares;
    		double share_val;
    		double total_val;
    		void set_tot();
    	public:
    		......
    };
    inline void Stock::set_tot() {
        total_val = shares * share_val;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.在什么情况下,编译器才会提供默认构造函数?在什么情况下你必须为类提供默认构造函数?
    3.有哪两种方式定义默认构造函数?在默认构造函数里通常应该做什么操作?
    4.析构函数在什么时候会被程序自动调用?
    5.创建的是静态存储类对象、自动存储类对象、通过new创建的对象,这三种情况下,析构函数在何时被自动调用?
    6.默认情况下,与给结构赋值一样,在给类对象赋值时(一个对象赋值给另一个对象),会执行什么操作?
    7.如下代码,可能会产生临时对象吗?为什么?这时会自动调用谁的析构函数?具体是在什么时候被调用的?

    int main() {
    	Stock stock1("NanoSmart", 12, 20.0);// 直接创建对象
    	stock1 = Stock("Nifty Foods", 10, 50.0);// 对象赋值(一个匿名对象赋值给一个对象)
    	...
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    8.参考下面代码,问:对象初始化与对象赋值,有什么区别?

    Stock stock1("NanoSmart", 12, 20.0);// 对象初始化(语法一)
    Stock stock2 = Stock("Boffo Objects", 2, 2.0);// 对象初始化(语法二)
    stock2 = stock1;// 对象赋值
    
    • 1
    • 2
    • 3

    9.在上面代码中,stock1与stock2都是自动变量,它们被放入哪块内存?析构的顺序是按什么规则?
    10.参考如下代码,可以将列表初始化语法用于类吗?如果可以,初始化的成员要与构造函数的什么匹配?

    Stock::Stock(const std::string& cmp, long n = 0, double pr = 0.0);
    ------------------------------------------------------------------
    Stock hot_tip = {"Derivatives Plus Plus", 100, 45.0};
    Stock jock {"Sport Age Storage, Inc"};
    
    • 1
    • 2
    • 3
    • 4

    11.看下面代码,编译器拒绝第2行代码,为什么?怎么解决(如何让成员函数不允许修改[调用对象])?

    const Stock land = Stock("Kludgehorn Properties");
    land.show();←编译器拒绝
    
    • 1
    • 2

    12.应遵守一规则:“只要类方法不修改调用对象,就应该将其他声明为const成员函数”,对吗?
    13.每个类都只能有一个析构函数吗?如果构造函数使用了new,则必须提供使用delete的析构函数吗?
    14.要比较两个对象的成员,提供一个比较成员函数,如下代码和图,能悟出什么知识点(隐式访问&显示访问)?

    const Stock& topval(const Stock& s) const;// 函数原型
    
    • 1

    假设要对Stock对象stock1和stock2进行比较,并将其中股价总值较高的那一个赋给top对象,则可以使用下面两条语句之一:

    top = stock1.topval(stock2);
    top = stock2.topval(stock1);
    
    • 1
    • 2


    15.看下面代码,引发一个小问题,如何解决?

    const Stock& Stock::topval(const Stock& s) const {
        if (s.total_val > total_val)// 问:这个大于号后的total_val确定是调用的对象的吗?
            return s; // 参数对象
        else
            return ?????; // 调用的对象
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    16.一般来说,所有类方法都将this指针设置为调用它的对象的地址。所以,以上代码,如下书写,是正确的吗?为什么?

    const Stock& Stock::topval(const Stock& s) const {
        if (s.total_val > this->total_val)// 其中,“this->”可缺省
            return s;
        else
            return *this;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    17.this是对象的地址,还是对象本身?
    18.对象能创建数组吗?同常规数组相比,用法有什么不一样的吗?
    19.看如下代码,花括号中的构造函数创建的是临时对象吗?创建10个元素,结果只初始化了3个,其余的元素默认是什么?这时就必须得为类提供什么构造函数了?

    const int STKS = 10;
    Stock stocks[STKS] = {
        Stock("NanoSmart", 12.5, 10),
        Stock();
        Stock("Monolithic Obelisks", 130, 3.25)
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    20.如下代码,可行吗?“声明类只是描述了对象的形式,决不能创建类数据成员”,所以,根本原因是什么?

    class Bakery {
    private:
        const int Months = 12;// 本身这句代码是不报错没问题的
        double costs[Months];// Error:a nonstatic member reference must be relative to a specific object
    
    • 1
    • 2
    • 3
    • 4

    21.以上代码的替代方案有哪两种?第一种是?为什么可行?第二种是?为什么可行?
    22.以下3种枚举分别有什么不同的含义?

    enum {RED, GREEN, BLUE};
    --------------------------------------------
    enum egg {Small, Medium, Large, Jumbo};
    enum t_shirt {Small, Medium, Large, Xlarge};// Error!冲突!因为egg(Small)与t_shirt(Small)位于相同的作用域内。
    --------------------------------------------
    enum class egg {Small, Medium, Large, Jumbo};
    enum class t_shirt {Small, Medium, Large, Xlarge};// OK!避免了上述问题,因为枚举量的作用域为类。
    ############################################
    enum egg_old {Small, Medium, Large, Jumbo}; // 无作用域
    enum class t_shirt {Small, Medium, Large, XLarge}; // 类作用域
    int main() {
    	egg_old one = Small;
    	t_shirt rolf = t_shirt::Small;
    	cout << (rolf == t_shirt::Small);// 1
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    第11章:使用类

    1.运算符重载,是怎么体现OOP思想的?可以看到下面代码,在重载“+”与“*”时使用了不同的参数类型,这也是OK的吗?

    Time Time::operator+(const Time& t) const {
    	Time sum;
    	sum.minutes = minutes + t.minutes;
    	sum.hours = hours + t.hours + sum.minutes / 60;
    	sum.minutes %= 60;
    	return sum;
    }
    Time Time::operator*(double mult) const {
    	Time result;
    	long totalminutes = hours * mult * 60 + minutes * mult;
    	result.hours = totalminutes / 60;
    	result.minutes = totalminutes % 60;
    	return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.重载+ - * / 等运算符后,这些运算符是专门给谁用的?
    3.友元有哪三种?C++发明友元,是为了解决什么问题?
    4.通过让函数成为类的友元,可以赋予该函数与类的哪个部分具备相同的访问权限?
    5.在为类重载几元运算符时(带几个参数的运算符),常常需要友元?
    6.请将下面代码转化为成员函数的调用?

    A = B * 2.75;
    
    • 1

    7.能用成员函数重写个重载运算符来解决如下运算吗?

    A = 2.75 * B;
    -------------
    Time Time::operator*(double n, Time& t);// OK or Not?
    
    • 1
    • 2
    • 3

    8.以上代码中的重载运算符成员函数会报错,具体报什么错?对于成员函数重载运算符,对参数个数有什么限定?
    9.可以用友元函数重载上述运算符,就没任何问题,那么友元函数最多能带的参数个数有什么限定?
    通过如下代码比对成员函数重载和友元函数重载,发现有何异同?这更进一步证明了什么?

    // 函数原型
    Time operator*(double n) const;
    friend Time operator*(double n, Time& t);
    -----------------------------------------
    // 成员函数
    Time Time::operator*(double mult) const {
    	Time result;
    	long totalminutes = hours * mult * 60 + minutes * mult;
    	result.hours = totalminutes / 60;
    	result.minutes = totalminutes % 60;
    	return result;
    }
    // 友元函数
    Time operator*(double mult, Time& t) {
    	Time result;
    	long totalminutes = t.hours * mult * 60 + t.minutes * mult;
    	result.hours = totalminutes / 60;
    	result.minutes = totalminutes % 60;
    	return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    10.友元函数是非成员函数,它使用的所有值(包括对象)都是显式还是隐式参数?
    11.请将下面代码转化为非成员函数的调用?

    A = 2.75 * B;
    
    • 1

    12.上面友元函数重载的*运算符,它的第一个参数能与第二个参数顺序互换吗?为什么?
    13.重载“<<”运算符,必须用友元函数吗?参考如下代码,如果用成员函数重载,会发生什么?

    void Time::operator<<(ostream& os);// 假设是成员函数重载<<
    -----------------------------------
    trip << cout;// 第1个操作数是Time类对象trip,第2个操作数是ostream类对象cout
    
    • 1
    • 2
    • 3

    14.如下代码,如果是“cout << time;”,那么cout是谁的别名?

    ostream& operator<<(ostream& os, const Time& t) {
        os << t.hours << " hours, " << t.minutes << " minutes";
        return os;
    }
    ----------------------------------------
    cout << time; <=> operator<<(cout, time);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    15.以上代码中,若不是友元函数,t.hours 和 t.minutes是能直接访问到的吗?
    16.如下代码,接受一个参数(其他参数有默认值的也算)的构造函数,会自动成为对象与参数类型之间的转换函数吗?
    为了避免意外的类型转换,C++新增了哪个关键字?是为了防止什么?

    Stonewt(double lbs);
    --------------------
    Stonewt myCat; // 创建一个Stonewt对象
    myCat = 19.6; // 使用Stonewt(double)将19.6转换为Stonewt对象
    
    • 1
    • 2
    • 3
    • 4

    17.转换函数的作用是什么?声明转换函数要注意哪三点?
    18.如下代码示例展示了转换函数的用法。你认为转换函数在C++中能发挥出哪些价值?
    原则上说,最好使用显式转换,而避免隐式转换。为了防止隐式转换,声明时要加上哪个关键字?

    // 函数原型
    operator int() const;// 对象转换为int类型的函数
    operator double() const;// 对象转换为double类型的函数
    ------------------------
    // 函数实现
    Stonewt::operator int() const {
    	return int(pounds + 0.5);
    }
    Stonewt::operator double() const {
    	return pounds;
    }
    ------------------------
    // 实际应用
    Stonewt poppins(9, 2.8);// 9 stone, 2.8 pounds
    double p_wt = poppins;// 使用到转换函数
    cout << "Convert to double => Poppins: " << p_wt << " pounds.\n";
    cout << "Convert to int => Poppins: " << int(poppins) << " pounds.\n";// 使用到转换函数,否则默认int(poppins)==128
    /*【输出】
    	Convert to double => Poppins: 128.8 pounds.
    	Convert to int => Poppins: 129 pounds.
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    第12章:类和动态内存分配

    1.静态类成员有一个特点:无论创建多少对象,程序都只创建一个静态类变量副本。所以用它能起到什么作用?

    /*public*/static int HowMany() { return num_strings; }
    
    • 1

    2.能在类声明中初始化静态成员变量吗?为什么?如果是初始化静态成员常量,是可以的吗?
    3.如下代码,为什么要用strcpy函数,而不能直接str = s;?

    StringBad::StringBad(const char* s) {
    	len = std::strlen(s);
    	str = new char[len + 1];
    	std::strcpy(str, s);
    	num_strings++;
    	cout << num_strings << ": \"" << str << "\" object created\n";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.如下代码创建两个构造函数,有什么问题吗?为什么?

    Klunk() { klunk_ct = 0; }
    Klunk(int n = 0) { klunk_ct = n; }
    
    • 1
    • 2

    5.类的复制构造函数的原型的格式是怎样的?
    6.列出五种会自动调用复制构造函数的情况?
    7.默认的复制构造函数的作用机理是?
    8.如果一些类的数据成员是通过new初始化的,就必须显式地定义什么?如果不这样做会有什么后果?
    9.浅复制与深度复制之间的区别是什么?
    10.类的赋值运算符的原型的格式是怎样的?
    11.赋值运算符的功能是什么?列出一种会自动调用赋值运算符的情况?
    12.默认的赋值运算符的作用机理是?
    13.在什么情况下需要显式地定义赋值运算符?
    14.下面代码展示了显式定义的复制构造函数和赋值运算符,有何异同?

    // 复制构造函数
    StringBad::StringBad(const StringBad& st) {
        num_strings++; // 处理静态成员的更新
        len = st.len;
        str = new char[len + 1];
        std::strcpy(str, st.str);// 复制字符串到新地址
        cout << num_strings << ":\"" << str << "\" object created\n";// 打印信息
    }
    // 赋值运算符
    StringBad headline1("Celery Stalks at Midnight");
    StringBad knot;// 自动调用默认构造函数初始化knot
    knot = headline1;// 赋值运算符被调用
    -------------------------------------
    StringBad& StringBad::operator=(const StringBad& st) {
    	/* 赋值操作并不创建新的对象,因此不需要调整静态数据成员num_strings的值。*/
        if (this == &st)// 对象赋值给它自己(若不作判断,释放内存操作可能删除对象的内容!)
            return *this;
        delete[] str;// 释放以前分配的数据(important!)
        len = st.len;
        str = new char[len + 1];
        std::strcpy(str, st.str);
        return *this;// 返回一个指向调用对象的引用,这样可以进行连续赋值
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    15.以下前两行代码有什么作用上的区别?后半部分代码为什么能判断是否输入为空行?

    str = new char[1];
    str = new char;
    ---------------
    char temp[MaxLen];// MaxLen = 81
    cin.get(temp, MaxLen);
    if (!cin || temp[0] == '\0') {// 
    	// TODO:判断出了输入为空行
    }
    /* 如果实现遵循了最新的C++标准,则if语句中的第一个条件将检测到空行,第二个条件用于旧版本实现中检测空行。*/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    16.(void*)0、NULL、nullptr,都可以表示空指针,那这三者有何区别?建议使用哪个?
    17.以下代码编译有问题吗?为什么?

    /* String是自定义的类,并且重载了[]运算符 */
    const String answer("futitle");
    cin >> answer[1];
    
    • 1
    • 2
    • 3

    18.在重载时,C++会区分常量和非常量函数的特征标吗?下面代码中同时存在两个对“[]”的重载有问题吗?

    char& String::operator[](int i) {
        return str[i];
    }
    ----------------------------------
    const char& String::operator[](int i) const {
        return str[i];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    19.在以上重载的基础上,如下代码的后4行有没有问题,如果没问题就说说它使用的是哪个重载的版本?

    String text("Once upon a time");
    const String answer("futile");
    cout << text[1];// ?
    cout << answer[1];// ?
    cin >> text[1];// ?
    cin >> answer[1];// ?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    20.静态成员函数可以使用非静态数据成员吗?为什么?
    20A.假设类成员的类型为String类或标准string类,如下代码所示,Magazine对象的复制构造函数和赋值运算符的逐成员复制是如何进行的?如果将一个Magazine对象复制或赋值给另一个Magazine对象,为完成深度复制,还需要重载Magazine类的复制构造函数和赋值运算符吗?简单来问,就是对于数据成员类型为类类型(而非基本数据类型)时,数据成员的复制是如何进行的?

    class Magazine {
    private:
        String title;
        string publisher;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    21.函数返回对象将自动调用什么函数?
    22.如果函数有两个参数且都是const修饰的,那么如果返回的是对象的引用,也应该声明为const吗?为什么?
    23.如下代码返回的是对象而不是引用,正确合理吗?为什么?

    Vector Vector::operator+(const Vector & b) const {
        return Vector(x + b.x, y + b.y);
    }
    
    • 1
    • 2
    • 3

    24.如果对象是用new创建的dynamic object,则在什么时机下其析构函数才会被调用?
    25.如下代码,delete可与定位new运算符配合使用吗?为什么?
    指针pc2指向的地址与buffer相同吗?如果非要delete pc2;,那么这是在释放pc2所指向的对象占用的内存吗?

    JustTesting(const string& s = "Just Testing", int n = 0) {
    	words = s;
    	number = n;
    	cout << words << " constructed\n";
    }
    ~JustTesting() {
    	cout << words << " destroyed\n";
    }
    void Show() const {
    	cout << words << ", " << number << endl;
    }
    ------------------------------------
    int main() {
    	char* buffer = new char[512];// get a block of memory
    	JustTesting* pc1, *pc2;
    	pc1 = new JustTesting("Heap1", 20);// place object on heap
    	pc2 = new (buffer) JustTesting;// place object in buffer
    	/* 下行代码是确保在内存单元不重叠,否则会出问题!其中指针pc3相对于pc2的偏移量为JustTesting对象的大小(字节为单位)。*/
    	// pc3 = new (buffer + sizeof(JustTesting)) JustTesting("Better Idea", 6);
    	cout << "Address # heap:" << pc1 << "	buffer:" << (void*)buffer << endl;
    	cout << "Content # pc1:@" << pc1 << ": "; pc1->Show();
    	cout << "Content # pc2:@" << pc2 << ": "; pc2->Show();
    	delete pc1;// OK
    	// delete pc2;// 删除pc2指向的对象?NO!会导致运行阶段错误!
    	delete[] buffer;// free buffer,这完全足够了,because object exists in this buffer!
    	cout << "Done";
    	return 0;
    }
    /*【打印:】
     * Heap1 constructed
     * Just Testing constructed
     * Address # heap:00826B48	buffer:00825EE8
     * Content # pc1:@00826B48: Heap1, 20
     * Content # pc2:@00825EE8: Just Testing, 0
     * Heap1 destroyed
     * Done
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    26.上面代码中,因为调用delete pc1;所以导致对应对象被析构,打印了“Heap1 destroyed”。不能调用delete pc2;的根本原因是什么?没有打印“Just Testing destroyed”即说明并没有调用pc2所指对象的析构函数,那该如何让pc2所指对象的析构函数被调用呢?为什么非要让pc2所指对象调用析构函数呢?

    第13章:类继承

    1.如下代码,能够使用C-风格字符串初始化std::string对象,根本原因是什么?

    Player(const string& firstname, const string& lastname);
    --------------------------------------------------------
    Player player1("Chuck", "Blizzard");
    
    • 1
    • 2
    • 3

    2.结合下图,基类的公有成员和私有部分与派生类的关联是怎样的?

    3.“创建派生类对象时,程序首先创建基类对象。” 那么,C++使用什么方式来完成这种工作?
    4.如果省略掉对基类的成员初始化列表,情况将如何?
    5.为什么派生类往往有个如下形式?派生类RatedPlayer构造函数的初始化列表会自动完成对基类[数据成员]的初始化吗?基类TableTennisPlayer并没有定义复制构造函数,这会产生问题吗?

    RatedPlayer::RatedPlayer(unsigned int r, const TableTennisPlayer& tp) : TableTennisPlayer(tp) {
        rating = r;
    }
    
    • 1
    • 2
    • 3

    6.释放对象的顺序与创建对象的顺序相同还是相反?所以首先执行谁的的析构函数?
    7.如果函数被声明为virtual,派生类要重写基类的方法,如果函数是通过引用或指针(而不是对象)调用的,它将根据什么来选择调用的函数?如果要声明虚函数,是在基类还是派生类中的方法中使用virtual关键字?如果不声明为虚函数则在调用关系上是什么结果?
    8.为什么经常在基类中将派生类会重新定义的方法声明为虚方法?方法在基类中被声明为虚的后,它在派生类中将自动成为虚方法吗?为什么建议在派生类声明中也使用关键字virtual?目的是为了指出什么?
    9.虚方法可以在派生类中必须重写吗?
    10.

  • 相关阅读:
    [PAT练级笔记] 67 Basic Level 1067 试密码
    chrome插件:content.js、background.js, options.js, popup.js之间的通信
    nginx反向代理与负载均衡
    深度学习与CV教程(4) | 神经网络与反向传播
    vscode使用restClient实现各种http请求
    SpringBoot SpringBoot 基础篇 4 基于 SpringBoot 的SSMP 整合案例 4.17 异常消息处理
    字符串思维题练习 DAY5(CF1137 B , CF 733D , CF 1360 F)
    linux进程间通信-FIFO,让你全方位理解
    黑马点评-02使用Redis代替session,Redis + token机制实现
    jenkins常见问题
  • 原文地址:https://blog.csdn.net/itzyjr/article/details/126222675