C++对象

1. 拷贝构造函数

作用: 想像变量一样,用赋值的形式对类对象初始化

例如:

class person{

、、、、、、、、

};

person p2 = p1;

默认有拷贝构造函数,如果自己写,要求的参数格式为(以person类为例)

person(const person & x);//以应用的形式

拷贝构造函数也是构造函数的一种,所以没有返回值,以类名为函数名

如果自己写,就要在自己写的构造函数内, 完整的用初始化列表的形式,把变量都赋值一遍,不如不写;

而且,自己写了拷贝构造函数,也要自己写构造函数,把类内变量在自己写的构造函数内初始化一遍,不如不写。

视频学习参考什么是拷贝构造函数?_哔哩哔哩_bilibili

2. 重载(overload)

 类内多个重名函数,但是参数列表不同,即便重名也不影响,灵活运用。

3. 多态

满足两个条件:(1)父类指针指向子类对象;(2)子类对虚函数重写;这种条件下父类指针调用虚函数,则是多态,理解为,同一件事,不同人干,结果不一样。

重写(override) 子类函数,函数名,返回值,参数列表,均与父类同名函数一致。

虚函数,父类内虚函数,virtual, 子类内只要与这个函数同名,无论加不加virtual,都是虚函数。

父类指针指向父类对象,调用虚函数,不存在虚实区别。

4. 类的多继承

一个类可以同时继承多个父类, 例如   class C: public A, public B

4.1 多个父类中有同名函数

// class 1
class A{
    public:
    void buy(){cout << "A" << endl;}
};


// class 2
class B{
    public:
    void buy(){cout << "B" << endl;}
};
 

// 派生类

class C: public A, public B{
    public:
    void buy(){cout << "C" << endl;}
};
class D: public A, public B{
    public:
    void cost(){cout << "D" << endl;}
};
int main(){
    C c;
    c,buy(); // 输出C,子类重写同名成员函数
    D d;
    d.buy(); // 输出报错,因为有两个父类里都有buy函数
    d.A::buy(); // OK 加了作用域解析符,输出 A
    d.B::buy(); // OK 加了作用域解析符,输出 B
    return 0;
}    

 多个父类中有同名函数,需要添加作用域解析符

4.2 菱形继承

菱形继承(二义性, 成员冗余)

例如, 基类是A, B继承了A,C页继承了A, D又继承了B和C,那么相当于D间接继承了A两次,这就造成了成员冗余,

class BC0
{
public:
    int K;
};
class BC1 : public BC0
{
public:
    int x;
};
class BC2 : public BC0
{
public:
    int x;
};
class  DC : public BC1, public BC2{
};
int main( )
{
    DC d;
    d.x = 1;       // error C2385: 对"x"的访问不明确
         //可能是"x"(位于基"BC1"中),也可能是"x"(位于基"BC2"中)
    d.BC1::x = 2;   // OK,from BC1
    d.BC2::x = 3;   // OK,from BC2
    d.K = 4;           // error C2385: 对"K"的访问不明确
    d.BC1::K = 5;  // OK,from BC1
    d.BC2::K = 6;  // OK,from BC2
    return 0;
}

此时类DC中有四个成员变量, 两个x 和两个K,造成了冗余,

解决方法: 加virtual关键字,实现虚拟继承

class A{}; class B: virtual A{}; class C: virtual A{};

class C : public B, public C{};

这样,就只会继承一遍A, 上述程序中d.K = 4; 就不会再报错了。

4.3 多继承下构造函数

子类对父类的继承,要在子类的构造函数中,先完成对父类的初始化,可以用初始化列表的形式

例如A是父类,B是子类,B的构造函数如果自己写的话,可以写成, B(): A(){},如果需要传递参数,可以写成,B(int n) : A (n){}

需要注意的是,在多继承情况下构造时,对基类的初始化,要先virtual,再非virtual,同等级别,就按照写的先后顺序,再是子类的成员初始化,最后是子类自己的构造函数。

详细参见C++ 多重继承-CSDN博客

 5.纯虚函数

纯虚函数的声明如下: virtual void func() = 0;纯虚函数一定是没有定义的,函数定义要在派生类中实现,有纯虚函数的类为抽象类,是不可以实例化的。纯虚函数也是应用于多态。

6. 引用和指针的区别

引用本身并不创建新的变量,指针是创建了一个新的变量,指向对应变量的地址。

7.迭代器和指针

迭代器和指针具有一些类似的功能,都有->和++的操作符,假设现在一个数组不知道大小,指针容易越界,迭代器是从begin()到end(),不会越界。(个人理解)

8.C++编译过程

预编译——>编译——>汇编——>链接

9.导入C函数的关键字

extern “C”;

此外,C++可以重载函数,C不可以

10. new和malloc的区别

1.new是关键字,malloc是函数

2.new不成功会报错,malloc不成功返回null;

3.new返回具体类型指针,malloc需要强制类型转换。

11. 深拷贝与浅拷贝

浅拷贝: 新对象简单复制原对象;

深拷贝:对原对象的引用或指针指向的内容也复制;

这样做的目的是在修改新对象时不会影响原对象;

需要显式的定义拷贝构造函数来实现深拷贝。

你可能感兴趣的:(c++,开发语言,1024程序员节)