c++ default override delete关键字

0.前言

c++11中,新增加了许多关键字与新用法。下面我们针对c++11里面的新特性,来看看这些关键字的用法。

1.default

在阅读项目源码时,看到许多default关键字,我们先通过一个例子来说明default的用法。

class Person {
    private:
        string name;
    public:
        Person(string _name) : name(_name) {}
};


int main(int argc, char const *argv[])
{
    Person *person = new Person(); // error
    return 0;
}

如上述代码,注释error一行的地方在IDE内会提示错误。

no matching constructor for initialization of 'Person'

在上面的代码中,person类定义了带参数的构造器,我们试图new一个person对象但是没带参数,此时将会去寻找默认构造函数。因为我们此时已经定义了有参数的构造函数,编译器并不会再生成默认构造函数,所以此时代码会报错,因为此时person类并没有默认的无参构造函数,臣妾做不到啊。

为了达到自动生成默认构造函数的目的,我们可以使用default关键字。

class Person {
    private:
        string name;
    public:
        Person() = default;
        Person(string _name) : name(_name) {}
        string getName() {return this->name;}
};

int main(int argc, char const *argv[])
{
    Person *person = new Person();
    cout<<"person name is: "<<person->getName()<<endl;
    return 0;
}

代码输出如下:

person name is: 

deafult解决的其实就是默认构造器生成的问题。那么我们稍微深入一点,到底什么情况下编译器会生成默认构造器?

1.如果积累带有默认构造函数,那么他的派生类也会生成默认构造器。
2.如果一个类中,含有类对象的数据成员变量,这个类会生成默认构造器。
3.如果一个类带有虚函数,这个类会生成默认构造器。
4.带有虚基类的类会生成默认构造器。

参考一下网络中搜索到的结论总结:
以下两个观点都是错误的:
1.任何类如果没有定义构造函数,则编译器会帮我们合成一个默认构造函数。
2.合成默认构造函数会对类中的每一个数据成员进行初始化。

只有在编译器需要默认构造函数来完成编译任务的时候,编译器才会为没有任何构造函数的类合成一个默认构造函数,或者是把这些操作插入到已有的构造函数中去。编译器需要默认构造函数的情况,总结起来就是:
1.调用对象成员或基类的默认构造函数。
2.为对象初始化虚表指针与虚基类指针。

2.override

写过java的同学对override关键字很熟悉。c++中,override关键字的功能跟java中基本是类似的,主要是在声明类成员函数时候使用。override是通知编译器,同时也提醒写代码的人,这个函数是重写了父类的虚函数。编译器会进行检测,如果这个函数没有真正重写负类的虚函数,那么编译器会提醒并报错。同时,程序员看到这个关键字也会明白,这个函数就是重写了父类的虚函数。

class A {
    public:
        virtual void f1();
        void f2();
};

class B: public A {
    void f1() override;
    void f2() override;
};

其中,B类中的f2函数,编译器会提示报错

only virtual member functions can be marked 'override'

3.delete关键字

我们之前就见过delete关键字,不过之前的delete关键字是与new关键字配合使用,用来释放内存的。从c++11以后,delete关键字有了新的用途:禁用某个类的成员函数。

class Person {
    private:
        string name;
    public:
        Person() = delete;
        Person(string _name): name(_name) {}
};

int main(int argc, char const *argv[])
{
    Person *persoon = new Person();
    return 0;
}

以我们前面的person类为例,如果我们在默认构造函数后面,使用的不是default,而是delete,则表示默认构造函数不能被使用,此时上面的代码会报错

call to deleted constructor of 'Person'

再看一个例子

class A {
    public:
        A() = default;
        A(const A&) = delete;
};

int main(int argc, char const *argv[])
{
    A a;
    A a2 = a;
    return 0;
}

此时编译器也会提醒我们

无法引用 函数 "A::A(const A &)" (已声明 所在行数:49) -- 它是已删除的函数C/C++(1776)

你可能感兴趣的:(c/c++,c++,default,override,delete)