2018-2019 C++期末複習資料(記錄一些知識點)

參考博客:https://blog.csdn.net/weixin_44187989/article/details/91830600

程序改錯題,指出程序中的錯誤語句並分析錯誤原因

下列類成員必須採用類內初始值或構造函數初始化列表進行初始化:

  1. 常量成員
  2. 引用成員
  3. 類對象成員
  4. 派生類構造函數對基類構造函數的調用

 

常量引用類對象+派生構造調用基類構造

————————————————

 

構造函數初始化列表的執行時間:

類內初始值

構造函數初始化列表

構造函數體

 

————————————————

 

補充:
靜態成員、常量成員都不能在類內初始化。但靜態整型常量成員可以在類內初始化如:static const int
靜態成員函數的說明和定義與靜態數據成員一樣,函數可以實現在類體內,也可以實現在類體外

————————————————

static成員函數只能訪問static成員,

常量必須初始化

引用必須初始化

構造函數沒有返回值

函數末尾聲明const不能改變類的數據成員

在類內private內函數無法被調用

派生類無法訪問基類private(派生類對象能通過成員函數訪問基類的pubilc和potect)

派生類使用構造函數,若基類構造函數要傳參則要初始化列表基類傳進去

多個基類中存在同名函數/同名數據成員,派生類同時繼承這多個基類,調用該同名函數或則和數據成員時要指明作用域防止二義性

閱讀程序,寫出程序的運行結果

————————————————

 

附:

一個派生類構造函數的執行順序:

第一步執行:虛擬基類的構造函數(多個虛擬基類則按照繼承的順序執行構造函數)。

第二步執行:基類的構造函數(多個普通基類也按照繼承的順序執行構造函數)。

第三步執行:類類型的成員對象的構造函數(按照初始化順序)。

第四部執行:派生類自己的構造函數。

 

虛基類:

虛基類子對象由最終派生類的構造函數通過調用虛基類的構造函數進行初始化(最終派生類的構造函數的成員初始化列表中必須列出對虛基類構造函數的調用,否則,表示使用該虛基類的缺省構造函數)。

 

由於最終派生類總是相對的,因此,從虛基類直接或間接派生的派生類中的構造函數的成員初始化列表中都要列出對虛基類構造函數的調用。

 

但只有用於建立對象的最終派生類的構造函數才調用虛基類的構造函數,此時最終派生類的所有基類中列出的對虛基類的構造函數的調用在執行過程中都會被忽略,從而保證虛基類子對象只初始化一次。

————————————————

對於析構函數:

最先構造的最晚被釋放

拷貝構造函數也要析構。做的時候前面寫的對的直接按棧順序寫析構函數

————————————————

++i:先增再用
i++:先用再增

 operator++(); // ++ 前綴

operator++(int); // ++ 後綴

operator--(); // -- 前綴

operator--(int); // -- 後綴

operator+=(int); // += 操作符

ascii A(65)  a(65+32=97)

————————————————

基類指針指向派生類對象,如果調用的函數是虛函數,則看指向的對象調用該對象類的函數,如果不是虛函數,就調用基類的同名函數。

基類對象引用派生類對象,如果是虛函數的多態進入,那麼使用的數據成員是派生類對基類繼承過來的數據成員

------------------------------------------

調用拷貝構造函數的情況:

  •  程序中需要新建立一個對象,並用另一個同類的對象對它初始化:

box2=box1//box2(box1)

  •  當函數的參數爲類的對象時

void fun(Box b) //形參是類的對象

{  }

int main( )

{Box box1(12,15,18);

fun(box1); //實參是類的對象,調用函數時將複製一個新對象b

return 0;

}

  •  函數的返回值是類的對象

Box f( ) //函數f的類型爲Box類類型

{ Box box1(12,15,18);

return box1; //返回值是Box類的對象

}

 

 

例子:#include<string>

#include<iostream>

using namespace std;

class Dog{

       string name;

       int age;

public:

       Dog(string name,int age):name(name),age(age){

              cout<<"invoking Dog constructor"<<endl;

       }

       Dog(const Dog& dog):name(dog.name),age(dog.age){

              cout<<"invoking Dog copy constructor"<<endl;

       }

};

class Person{

       string name;

       Dog dog;

public:

       Person(string name,Dog dog):name(name),dog(dog){//這裏是同類對象初始化調用拷貝構造

              cout<<"invoking Person constructor"<<endl;

       }

};

int main()

{

       Dog dog("Fido",4);

       Person p1("zaphod",dog);//這裏先是函數調用的參數裏類對象,調用拷貝構造

       Person p2 = p1;

       return 0;

}

 

並且p2=p1時,person只有默認拷貝函數(無參),但是person類裏包含的dog是有拷貝構造的,所以會調用dog的拷貝構造

 

 

 

 

 

 

 

 

 

例子:

#include <iostream.h>

class A

{

       public:

              A(int anInt = 0 ):i(anInt)

              {

                     cout << "A::A( )" << endl;

              }

              A(const A& anA)

              {

                     cout << “A::A(const A&)” << endl;

                     i = anA.i;

              }

              int getI( ) const

              {

                     return i;

              }

              ~A( )

              {

                     cout << "A::~A( )" << endl;

              }

       private:

              int i;

};

class B

{

       public:

              B( )//調用B的默認構造函數

              {

                     cout << "B::B( )" << endl;

              }

              B(const A& anA): a(anA)

              {

                     cout << "B::B(constA&) " << endl;

              }

              virtual void f( )

              {

                     cout << "B::f( )" << endl;

                     cout << a.getI( ) << endl;

              }

              virtual ~B( )

              {

                     cout <<"B::~B( )"<<endl;

              }

       private:

              A a;

};

class D : public B

{

       public:

              D( )

              {

                     cout << "D::D( )" << endl;

              }

              D(const A& anA): a(anA)//A的同類初始化調用拷貝構造

              {

                     cout << "D::D(constA&)" << endl;

              }

              void f( )

              {

                     B::f( );

                     cout << "D::f( )" << endl;

                     cout << a.getI( ) << endl;

              }

              ~D( )

              {

                     cout << "D::~D( )" << endl;

              }

       private:

              A a;

};

void main( )

{

       A a(10);

       B* pB = new D(a);

       pB->f( );

       delete pB;

}

一、選擇題

P57 編譯器會根據函數的參數表來區分函數的不同重載形式

P223 運算符函數的調用 不必須使用關鍵字operator,可以隱式調用

P97 隱式調用無參構造函數

P290 try塊中不必須包含throw語句

構造函數可以被重載,因爲構造函數可以有多個且可以帶參數。

析構函數不可以被重載,因爲析構函數只能有一個,且不能帶參數。

P117 靜態數據成員屬於類

P117 靜態成員只能訪問靜態成員,但靜態成員可以被非靜態成員訪問

P118 構造函數中可以對靜態數據成員賦值

P117 靜態數據成員遵守訪問權限的限定規則

P255 成員函數模板當編譯器遇到程序中對函數模板的調用是,由編譯器實例化爲可執行的模板函數

 

基類中子對象由基類初始化

虛基類子對象的初始化由最終的派生類完成

不能在函數中新建一個變量,並將其引用返回

P112 拷貝構造函數不能在類中進行函數重載

P110 P162 無論基類的拷貝構造函數是自定義和合成的版本,都可以執行

P110 通常拷貝構造函數可以只能有一個參數,是對同類的某個對象的引用

P96 構造函數沒有返回類型,即不允許在函數體重使用return語句

 

A*const p=new B;,其中類B是從類A直接派生得到的,那麼:

P164 p是基類指針,所以只能訪問B中基類部分

P144 非public基礎方式會改變構造函數的訪問權限,導致不能實例化對象

類B要實例化必須有一個無參的或提供全部缺省參數的構造函數

P164 通過指針p,可以訪問基類中的public訪問權限成員函數或者數據成員

 

[ ] 運算符可以被重載

 

四、 程序填空題

template (注意拼寫)

ostream

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章