C++:类-基本

类的基本思想是数据抽象(data abstraction)封装(encapsulation)。数据抽象是一种以来于接口(interface)和实现(implementation) 分离的编程技术。

接口与实现分离

接口方在头文件中。 实现方在cpp文件中。

使用预编译指令,避免多次引入头文件

#ifndef ABC_H
#define ABC_H


class ABC{
    
};


#endif

构造函数

默认构造函数

  • 如果没有显示定义构造函数,则编译器默认地隐式地定义一个默认构造函数合成地默认构造函数以此规则初始化类地数据成员:有初始值用初始值来初始化;没有的默认初始化。
  • 合成地默认构造函数不可靠:内置类型或复合类型(指针、数组)成员,当为定义初始值时, 其值将是未定义的。
  • 类中包含 没有默认构造函数 的类类型时,不能初始化。
class A{
    A() = default;  //显示地要求编译器生成默认构造函数
};
  • 使用默认构造函数时不要()
A a();  //定义了一个函数
A a;    //使用默认构造函数构造了一个对象

构造函数初始值列表

必显式地初始化的成员,必须通过构造函数初始值列表为其初始化,初始化的顺序与他们在类定义中出现的顺序一致,与初始值列表中出现的顺序无关

class A{
    public:
        A(int ii):ri(ii), i(ii){}   //i先被初始化,ri后被初始化
    private:
        const int i;
        const int ri;
};

委托构造函数(delegating constructor):使用它所属类的其他构造函数执行自己的初始化过程。优先执行受委托的函数函数体,再执行委托者的函数体

class A{
    public:
        A(int a, b);
        A(int a) : A(a,0);  //委托构造函数
};

隐式的类类型转换-转换构造函数

只接收一个参数的构造函数->定义了转换为此类类型的隐式转换机制->转换构造函数(converting constructor)

  • 编译器只会自动地执行一次转换
  • 可将构造函数声明为explicit来阻止隐式转换。但还是可以强制地进行。
class A{
    public:
        A(int a);
        explicit A(double b);
}

A a = 10
A b = 10.0; //错误
A b = A(10.0);  //正确

友元

使类允许其他类或函数访问它的非公有成员。
(部分编译器允许在尚无友元函数的初始声明的情况下声明友元)

  • 友元关系不可传递
  • 类和非成员函数的声明不是必须出现在它们的友元声明之前
  • 友元函数可以在类内部定义,但也必须在类外部声明该函数从而使该函数可见。
class A{
   friend void function();
   friend class B;
   friend void C::function();
};

拷贝

不主动定义,编译器将替我们合成->将对对象的每个成员执行拷贝。(类需要分配类对象之外的资源时,不能正常工作)。


类型成员

类内定义类型别名。
同样受public/private限制

class A{
   public:
        typedef int INT;
        using LL = long long;
};

explicit关键字

C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).
explicit用于阻止隐式的类型转换,如:

    class A{
    public:
       explicit A(int i); 
    };
    A a = 1;    //编译将失败 

const关键字-常量成员函数

  • 修饰了隐式this指针的类型
  • 修改成员变量的成员函数-修改函数(mutator
  • 只进行检查不修改成员变量的成员函数-访问函数(accessor) 在成员函数后加const,来表明其是访问函数
class A{
    public:
        int get() const;
        
};

在标记为const的成员函数中修改成员变量,将编译错误

基于const的重载

常量对象不可调用非常量版本的函数;非常量对象虽然可以调用常量版本的函数,但非常量版本的函数是更好的匹配。

class A{
    public:
        void function() const;
        void function();
};

const A a;
a.function(); //->调用非常量版本的
const A ca;
ca.function(); //调用常量版本的

operator[]返回值的问题

class A{
  ......  
};
A from;
A to;

现在的目的是将from[i]复制到to[i]

to[i] = from[i];

如果operator[]返回常量引用,则to[i]不能出现在等号左边。
如果operator[]返回普通引用,那么在编译中就会出现诸如from[i] = to[i]的表达式,这样的设计是不够优秀的。
可使用const标识

class A{
  public:
    const A &operator[](int i) const;
    A &operator[](int i);
};

定义在类内部的成员函数是自动inline的。

可变数据成员 - mutable关键字

变量声明时加入mutable关键字,即使在const成员函数中,也可以改变该成员。

静态成员

  • 静态数据成员的初始化必须在类外部进行
  • 在外部定义静态成员时不需要重复static关键字,该关键字只能出现在类内部。
  • 静态数据成员可以是不完全类型
  • 静态成员可以做默认实参(非静态成员不能作默认实参
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绫零依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值