抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

见到好多没见过的东西,记录下来。

构造函数

原来构造函数还可以这样写:

class myDate {
private:
    int year;
    int month;
public:
    myDate() : year(2021) {};
    myDate(int y) : year(y) {};
    myDate(int y, int m) : year(y), month(m) {};
};

使用new创建对象加与不加括号的区别:

  • 不加括号时,对于有自建的构造函数,正常执行,如果没有自建构造函数,系统只为成员变量分配空间不初始化,例如int型会出现随机值的情况。

  • 加括号时,就算没有自建构造函数,系统在为成员变量分配内存的同时赋初始值,例如int初始值是0

不加括号且没构造函数的下场:

int main() {
    auto *d = new myDate;
    std::cout << d->getYear(); // 39984272
}

定义指针不会触发构造函数

myDate *p;

复制构造函数

myDate::myDate(const myDate &other) {
    std::cout << "复制构造函数执行啦!" << std::endl;
    year = other.year;
}
int main(){
    myDate p;
    p.setYear(1000);
    myDate p1(p);
    std::cout << p1.getYear(); // 1000
    return 0;
}

p对象的year属性完整的复制给了p1对象

不写复制构造函数就是全部属性复制,写了就相当于重写了,按照自己指定的复制

自动调用复制构造函数的情况有3种:

  • 实例化类的时候传入要复制的类
  • 函数F参数中有类A的对象时,会复制类A
  • 函数F返回值是类A的对象,会复制类A

类型转换构造函数

int main() {
    myDate p(2000);
    std::cout<<p.getYear()<<std::endl;
    p = 2021;
    std::cout<<p.getYear()<<std::endl;
}

/*
output:
    构造函数:y = 2000
    2000
    构造函数:y = 2021
    2021
*/

p = 2021,表面上看这是一条赋值语句,十几箱,他将2021创建为临时myDate对象,然后使用这个对象为p赋值。

析构函数

~myDate(){
    std::cout<<"析构函数执行啦!"<<std::endl;
}

析构函数没有参数也没用返回值,会在对象消亡时执行。

释放对象指针数组内存空间

int main(){
    myDate *ss[2] = {new myDate(2020),new myDate(2021)};
    delete ss[0];
    delete ss[1];
    return 0;
}

/* output:
    构造函数:y = 2020
    构造函数:y = 2021
    析构函数执行啦!
    析构函数执行啦!
*/

类的静态成员

静态变量

全局变量是指在所有花括号之外声明的变量,其作用域范围是全局可见的,即在整个项目文件内都有效。使用static修饰的全局变量是静态全局变量,其作用域有所限制,仅在定义该变量的源文件内有效,项目中的其他源文件中不能使用它。

使用static修饰的局部变量是静态局部变量,即定义在块中的静态变量。静态局部变量具有局部作用域,但却有全局生存期,也就是说,静态局部变量在程序的整个运行期间都存在,它占据的空间一直到程序结束才释放,但仅在定义它的块中有效,在块外不能访问它。

静态变量均存储在全局数据区,静态局部变量只执行一次初始化。

函数中声明的静态变量仅在函数体中可见。

类的静态成员

静态成员变量是类的所有对象共享的。

静态函数里不能访问类中的非静态成员,只能处理类中的静态成员变量。

静态函数与静态函数之间、非静态函数与非静态函数之间是可以相互调用的。

非静态成员函数可以调用静态成员函数,静态成员函数不能调用非静态成员函数。

类中的静态成员变量只能在类外赋值,写法如下:

class Obj{
    static int num;
};
int Obj::num = 1;

访问类中的变量的3种方式:

cout<<Obj::num;

const auto p = new Obj;
cout<<p->num<<endl;

Obj p;
cout<<p.num<<endl;

类中的常量成员和常引用成员

常量对象不能调用非常量成员函数:

#include <iostream>
using  namespace std;

class Obj{
public:
    Obj(){}
    void set() {
        cout<<"普通成员函数"<<endl;
    }
    void get() const {
        cout<<"常量成员函数"<<endl;
    }
};

int main(){
    Obj o;
    o.get();
    o.set();

    const Obj co;
    co.get();
    co.set(); // error!
    return 1;
}

此时为set添加一个常量成员函数:

void Obj::set() const{
    cout<<"常量成员函数"<<endl;
}

此时就不报错了,可以看做重载函数,编译器会自动找到常量成员函数调用。

类中的常引用型变量必须在构造函数初始化,不能在程序中修改对象中的引用,否则会报错。

评论