[面向对象] 类

laobei-uu / 2024-06-10 / 原文

1. 类和对象

注意点:

  • (C++11之前)在类体中不允许对数据成员进行初始化

    class A {
        int a = 0;   // 在一些老版本的编译环境上会出错
    };
    
  • 类中的成员不能是自身类的对象

    否则会导致无限递归,最终栈溢出,因此会报编译错误。

    但是可以放自身类的指针或引用。

  • 若类A中含有成员类B,则类B需要提前声明

  • 数据成员不能用auto、register、extern修饰;成员函数不能用extern修饰


2. 拷贝构造函数

注意点:

  • 形参必须是对象的引用,&不能省略,否则会向上文所述的无限递归。

  • 编译构造优化

  • 要特别注意浅拷贝的问题

    举个例子

    class A {
        char* name;
        ~A() { delete[] name; }
    };
    

    当调用拷贝构造函数的时候,编译器会无脑复制一份数据到新对象,此时两个对象中name指向同一个地址,当两个类调用析构函数时,name会被delete两次,第二次会出错。

    这种情况必须自己写拷贝构造函数。

  • 对象作为参数传递时,用引用或者指针好一点,可以避免一次拷贝构造,减少开销


3. 静态成员

作用:为了解决同类对象间的数据共享问题,实际就是共享变量

静态成员在整个内存中只有一份,位于静态区。

在编译器遇到初始化语句时,就为其分配空间。

两种初始化方法:

  • 在类内初始化:必须加static修饰符
  • 在类内声明,要加static;在类外初始化,不加static

静态成员函数只能访问静态成员,因为非静态成员有对象才存在;相反,非静态成员函数可任意访问静态、非静态成员。在⼀般的成员函数中都隐含有⼀个this指针,⽤来指向对象自身,而在静态成员函数中没有this指针,这是无法访问非静态成员的技术原因。但是若向静态函数中传入对象,则可以访问对象中的非静态成员。

4. 友元

允许⼀个类授权另⼀个类的对象(友元类)、某个成员函数(友元成员)或外部函数(友元函数)访问其对象的非公有成员,而不允许整个程序访问。是类的封装性与执行效率的折中。

Java保留了静态成员,舍弃了友元机制。


5. 对象嵌套

比如类A中有成员变量类B,则在实例化A的时候,先调用B的构造函数,再调用A的构造函数(先里后外)

另外,在A的构造函数中,推荐使用构造函数初始化列表,来初始化B。