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

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值