C++问答--续

来源:互联网 发布:幂学集训营怎么样知乎 编辑:程序博客网 时间:2024/06/05 03:51
33.new和delete比 malloc和free有哪些优点?
  new和delete完成与malloc和free相似的功能,但是它们相比之下有以下优点:
  i.用new自动分配空间时容量是自动计算的,不必使用sizeof运算符,所以能够分配到足够的空间以容纳指定类型的对象,避免发生错误。
  ii.用new分配内存后将自动返回指定对象类型的指针,而用malloc则需显式的使用强制类型转换。
  iii. new和delete都可以重载,而malloc和free不存在此功能。


34. C++中可以使用printf()和scanf()吗?
  可以,因为C++是兼容C的功能的。但是C++中有自己的输入输出符号:<<和>>。例如语句cout<<"Hello"<<" world!\n"将在屏幕上输出Helloworld!并换行。cout,cin与<<和>>连用可以处理C++的任何内部数据类型。与printf和scanf相比它们具有如下优点:安全,编译器会静态地事先得知变量类型而不是由%动态获得;简单快速,不易出错;而通过重载运算符<<和>>,可以对用户定义的对象直接进行输入输出操作,这是printf和scanf所不能及的。

35.C++中的输出cout<<能够指定输出数据的域宽和精度吗?
  可以通过设置格式标志来完成,另外流类ios还有三个成员函数来设置格式参数。它们分别是:
  int width(int w);//设置域宽,w为新域宽,返回以前的域宽。
  int precision(int p);//设置精度,p为设置的精度,返回原来的精度值。
  char fill(char ch);//设置填充字符,ch为新的填充字符,返回原来的值。
  它们都可以由cout调用。


36.如何向函数传递数组?
  对于传递的一维数组,形式参数可以写成指针、有界数组、无界数组三种方式,例如voidfun(int *x)或者void fun(int x[10])或者void fun(intx[])。这三种方法效果相同,在调用时实参均应该是指向数组的指针。传递多维数组时,除第一维外其余各维大小必须指定,如voidfun(int x[][2][6])。

37. 我如何才能防止其他的程序员看到我的类的私有成员从而维护数据封装性呢?
  这个问题本身就存在问题。封装针对的是编码,而不是程序员。
  其他程序员看到你编写的类的私有成员,并不意味着这个类的封装性被破坏了,只要这些程序员不依赖于他们所看到的私有成员编写他们的程序,那么你的类的封装性就没有受到任何影响。"私有"这个词是针对类而言的,不是针对你和其他程序员。


38.封装是一种安全机制吗?
  不是。
  封装并不等于安全。封装是用来防止错误发生的,封装不能用来防间谍。


39.可以向构造函数传递变元吗?
  可以。通过向构造函数传递变元,可以对对象进行特定的初始化。

40.如何向函数传递对象?
  传递对象参数可以和传递其他类型的参数使用相同的方法。对象可以通过传值方式传递给函数,也就是传递给了函数一个拷贝。由于是相当于创建了一个新对象,那么它的构造函数和析构函数是否要执行呢?结果是这样的:新对象没有执行构造函数,但是函数结束时执行了析构函数。原因是新对象应该保持原对象的状态,因此不能执行构造函数重新初始化,而是执行拷贝构造函数,而最后这个拷贝还是要被撤销的,所以要执行析构函数。当然,如果希望对象能够被函数改变也可以向函数传递对象的引用或者指针。

41. 为什么友元关系不具有传递性,也不能通过继承得到?
  很明显,这么做是合情合理的。拿生活中的朋友关系类比:我宣称你是我的朋友,但这并不代表我也认为你的儿女或者你的朋友也是我的朋友。
  对于你朋友的儿女,你不一定信任,这说明朋友关系不能继承。如果class C声明class Base是一个友元类,并且classDerived是class Base的派生类,class Derived并不能自动的成为classC的友元。
  对于你朋友的朋友,你不一定信任,这说明朋友关系不能传递。如果class Bob声明class John是一个友元类,并且classJohn声明class Salla是一个友元类,class Salla并不能自动的成为classBob的友元类。


42. 如何在一个构造函数的内部调用另一个构造函数?
  这是不可能办到的。如果你调用了另一个构造函数,编译器将创建一个临时局部对象,而对于当前的对象起不到任何初始化作用。如果想要两个构造函数共享代码,可以创建一个私有成员函数initial(),在两个构造函数中分别调用它即可。

43. 对于类C来说,缺省构造函数一定是C::C()的形式吗?
  不是这样的。
  缺省构造函数是这样一类构造函数:调用它时可以不给出任何参数。所以不带任何参数的构造函数当然是缺省构造函数,比如:
  class C
  {
   C(); //缺省构造函数
  };
  但是,缺省构造函数也可以带有参数,只要这些参数都具有缺省值即可,比如:
  class C
  {
   C(int a=0, int b=0); //缺省构造函数
  };


44.为什么含有静态成员的类产生链接错误?
  产生这种错误的原因通常是编程者没有满足这样一条原则:类的静态数据成员必须被显式的定义,并且只能在一个编译模块中定义一次。如果你违反这一原则,就会得?quot;undefinedexternal" linker error。举例说明:
  // Fred.h
  class Fred {
   public:
   // ...
  private:
   static int j_; // 声明静态数据成员 Fred::j
   // ...
  };
  你必须在某个文件中定义Fred::j,否则链接不能通过,比如在Fred.cpp文件中定义它:
  // Fred.cpp
  #include "Fred.h"
  int Fred::j_ = 0;


45.局部对象的析构顺序是怎样的?
  局部对象按照它们建立顺序的反顺序进行析构。最早创建的对象最晚被析构。
  在下面的例子中,b的析构函数首先被调用,然后是a的析构函数。
  void f()
  {
   C a;
   C b;
   //……
  }


46. 能够重载类的析构函数吗?
  不能。
  对于一个类来讲,只能有一个析构函数,也一定是class_name::~class_name()的形式。析构函数没有任何参数,也没有返回值。我们不能传递给析构函数什么参数,因为我们不能显式的调用析构函数。


47. 如果我的对象是通过new创建的,那么我可以显式的调用析构函数清除这个对象吗?
  不能。
  你必须通过delete来清除这个对象。delete操作自动调用相应的析构函数,但是它比析构函数多做了一件重要的事情,它释放了对象本身占有的内存。需要铭记在心的是:delete做了两件事情,它调用了析构函数,并且释放了对象占用的内存。


48.说明指针变量和引用变量时,*或&应该与类型名连在一起还是变量名连在一起?
  当定义单个变量时这两种做法是一样的,只是反映了不同的风格而已,可以认为与类型名连在一起时得到一种指针类型。但是实际上并非如此,当多个变量同时定义时也许会出现问题,如int*a,b;将会定义一个指针类型变量a和一个整型变量b。因此只要清楚真正的含义,在实际应用时可以灵活一些而不会出错。

49. 如何进行操作符重载?
  操作符重载是十分有用的,特别是在面向对象的程序设计中,可以对自定义的对象直接用操作符连接,增强了直观性,例如重载加号+使它完成两个复数(用户定义的类)的加法。进行操作符重载时需要用到关键字operator,为某个类的对象重载操作符的成员函数定义形式为:returntypeoperator#(para-list);其中returntype是操作后返回的数据类型,通常是参与计算的对象的类型,#代表被重载的操作符,当#是单目操作符时参数表为空,当#为双目操作符时参数表中将是右操作数。也就是说是操作符左边的对象调用的函数。也可以用friend来重载关于类的运算符,这时函数将不是类的成员(没有this指针)。这样重载函数将显式的传递操作数,所以重载单目操作符将有一个参数,而重载双目操作符将有两个参数。但是不能用friend重载=,(),->运算符,而且参数需要是引用类型。

50. 在函数定义中使用const修饰符有何作用?
  关键字const可以说明常量,但是在函数定义中有更大的作用。当函数的参数是指针或者引用变量时(非传值参数),如果前面加修饰符const,则可以避免被指向或被引用的变量。当成员函数被const修饰时,例如voidfun() const;则表示该函数不会对调用它的对象产生影响。

51. 派生类可以继承基类的哪些部分?
  基类中的所有声明为public和protected的成员,派生类都可以继承,但是声明为private的部分,派生类则无权继承,这是为了将来基类中的(私有)成员一旦修改不会影响到其派生类。

52. public,protected,private有什么区别?
  它们都是类成员的访问级别,public标注的成员具有公有级别,也就是其他函数或者类的对象都可以访问它;private表示私有成员,它们不能被本类以外的对象或者函数引用;protected修饰的成员是保护成员,除了本类或本类的派生类可以存取外其他都无权访问。

53. 为什么要使用模板?
  有些操作对不同数据类型的数据操作相同,但是不得不对各个数据类型分别编写代码。为了让程序更加简洁通用,用template关键字将不同类型数据的共同操作定义成模板,以后某个类型的数据需要进行这个操作时就可以只指定数据类型以后直接调用该模板。可以编写模板函数,也可以编写模板类(可以根据不同的数据类型生成不同的对象),定义时只需在前面加上template,T表示程序中待定的数据类型。模板函数在调用时无需显式指定数据类型,直接调用即可;模板类调用时需在程序中需要指定数据类型的尖括号内给出具体的数据类型(如int)。

54. C++中可以嵌入汇编吗?
  可以的,通过关键字asm可以将汇编语言直接嵌到C++程序中。语法为:
  asm("string")或者asm instru或者asm{instrusequence},其中string,instru,instrusequence都是传给汇编程序的汇编语句。如果对汇编语言很精通,有时候在C++程序中嵌入汇编代码将会大大提高程序的效率。
原创粉丝点击