Primer (十三)

来源:互联网 发布:java就业培训教程 编辑:程序博客网 时间:2024/04/29 17:40

class A {    public:    A() = default; // 因为有自定义的构造函数,覆盖了默认构造函数,用default可以暴露出默认构造函数    A(int input):a(input),b(0){} // 构造函数不能是const的    void func1() const {cout<<a<<endl;} // 定义在类内的,默认为内联函数    inline void func2() const {cout<<b<<endl;} // 显式定义为内联    void func2(int input) const; // 对func2的重载,声明在类内,定义在类外    void func3() const {a++;cout<<a<<endl;} // const常量成员函数可以修改带mutable参数的成员变量    private:    mutable int a; // 带mutable,可以被任何成员函数修改    int b;};inline void A::func2(int in) const { // 在类外,显式定义为内联
    cout<<a+b+in<<endl; // 推荐使用声明在类内,定义在类外,类外显示式声明内联的方式,内联函数定义与类在同一个
头文件中}class B {    private:    std::vector<A> bbb{5,A(10)}; // 推荐使用类内初始值初始化,初始化只能用=或者{}};main () {    A a(10);    a.func1(); // 10    a.func2(); // 0    a.func2(20); // 30    a.func3(); // 11    B b;    return 0;}class C {    public:    C& func1() {a++;return *this;} // 返回对象的引用    C func2() {a++;return *this;} // 返回对象的复制    const C& func1() const {return *this;} // 返回对象的常引用,对于const成员方法,如果返回的是引用,必须是
常引用,因为默认传递进去的this是const C *const this,返回的*this是const C&,这里是func1的重载,函数有没有结尾
const也属于重载,const对象只能调用const函数,非const对象会优先调用非const函数    int a=10;};main() {    C c;    c.func1().func2(); // 12 先返回引用,然后返回复制    cout<<c.a<<endl;     c.func2().func1();// 13 先返回复制,用复制加一,对象c只加一了第一次    cout<<c.a<<endl;    const C d;    cout<<d.func1().a<<endl; // d是一个const,会使用重载的const func1,返回的是常引用,此时不能再调用func2
因为常引用不能改变a,除非a是mutable
    return 0;}class C {    public:    C& const f1() const{f3();return *this;} // f1的const重载
    C& f1() {f3(); return *this;}    private:    void f3() const {cout<<a<<end;}; // 更好的方法是,两个重载都调用private的第三个方法,因为f3定义在类内,
是内联的,所以并没有函数多次调用的开销,public里面的重载只控制返回类型是否为const,不做逻辑    a=10;}p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Monaco; color: #34bc26; background-color: #000000; background-color: rgba(0, 0, 0, 0.85)}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Monaco; color: #f4f4f4; background-color: #000000; background-color: rgba(0, 0, 0, 0.85)}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Monaco; color: #cd7923; background-color: #000000; background-color: rgba(0, 0, 0, 0.85)}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Monaco; color: #5230e1; background-color: #000000; background-color: rgba(0, 0, 0, 0.85)}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #f4f4f4}span.s3 {font-variant-ligatures: no-common-ligatures; color: #34bc26}span.s4 {font-variant-ligatures: no-common-ligatures; color: #cd7923}span.s5 {font-variant-ligatures: no-common-ligatures; color: #c33720}

class A; // 声明A类,为了D类可以声明

class D { // D类提前声明了,但是由于形参中有A类,所以A类又要提前声明

    public:

    void function(A);

};

class A { 

    friend class B; // 声明B类是A类的友元类,可以访问A类的私有成员,友元

类B不用提前声明

    friend void D::function(A); // 声明D类的function可以访问A类的私有

成员,因为用到了D类,所以必须提前声明D类

    int a=10;

};

class B { 

    public:

    void function(){A a;cout<<a.a<<endl;} // 定义中用到了A类,所以A类

要提前声明

};

// 友元关系不能传递,每个类定义自己的友元

p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Monaco; color: #f4f4f4; background-color: #000000; background-color: rgba(0, 0, 0, 0.85)}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Monaco; color: #cd7923; background-color: #000000; background-color: rgba(0, 0, 0, 0.85)}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Monaco; color: #f4f4f4; background-color: #000000; background-color: rgba(0, 0, 0, 0.85); min-height: 32.0px}span.s1 {font-variant-ligatures: no-common-ligatures; color: #34bc26}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font-variant-ligatures: no-common-ligatures; color: #c33720}span.s4 {font-variant-ligatures: no-common-ligatures; color: #f4f4f4}span.s5 {font-variant-ligatures: no-common-ligatures; color: #cd7923}

int in=5; // 外围全局变量in

class A { 

public:

    void function() {

        cout<<::in<<endl; // ::in表示in使用的是最外层的类外变量

        cout<<in<<endl; // 这里的in先查找类内的声明,然后再查找全局变量

    }   

private:

    int in=10; // 类内声明,在function中覆盖类外的in

};

int main() {

    A a;

    a.function(); // 5 10

    return 0;

}