类和对象(C++对象模型和this指针,友元)
美丽新科技BLOG

类和对象(C++对象模型和this指针,友元)

刘纪彤
2年前发布

类和对象(C++对象模型和this指针,友元)

C++对象模型和this指针

在C++中,类内的成员变量成员函数分别存储,且只有非静态成员变量才会存储在类的对象上。

//2-7-1
#include<iostream>
using namespace std;
class example
{
    //example构造函数
    example()
    {
        exp1=0;
        cout<<"example构造函数调用"<<endl;
    }
    //非静态成员变量占对象空间
    int exp1;
    //静态成员变量不占对象空间
    static int exp2;
    //函数也不占对象空间,所有函数都是共享的。
    void func()
    {
        cout<<"func函数"<<endl;
    }
    //静态函数也是一样的
    static void func2()
    {
        cout<<"func函数"<<endl;
    }
};
int main()
{
    cout<<"类占空间"<<sizeof(example)<<endl;;
}

输出结果:

类占空间4

如果我们把其他都注释掉,只留下exp1会发生:

输出结果:

类占空间4

this指针

C++提供了一个特殊的指针使得这个指针指向被调用的成员所属的对象,就是this指针。

this指针是隐含的,是无需自行定义的。

用途:

  • 当形参和成员变量同名的时候用以区分,不过,这一点可以通过在命名规范来解决。(2-7-2)
  • 在类的非静态成员函数中返回对象本身,可使用return *this(2-7-3)
//2-7-2
#include<iostream>
using namespace std;
class example
{
    public:
    void func(int a)
    {
        //this指针区分同名成员变量和形参
        this->a=a;
    }

    int a;
};
int main()
{
    example ex;
    ex.func(10);
    cout<<ex.a<<endl;
}
//2-7-3
#include<iostream>
using namespace std;
class example
{
    public:
    int a;
    example& func(int a)
    {
        this->a=a;
        return *this;
    }
};
int main()
{
    example ex;
    ex.func(10).func(20);
    cout<<ex.a<<endl;
}

C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针,否则会报错

    //2-7-4
    #include<iostream>
    using namespace std;
    class example
    {
        public:
        int a;
        example& func(int a)
        {
            this->a=a;
            return *this;
        }
    };
    int main()
    {
        example* ex=NULL;
        ex->func(10).func(20);
        cout<<ex->a<<endl;
    }

上面这串代码会报错,因为空指针中不能调用成员函数,但是如果把func函数中的this指针去掉就不会报错。

const修饰成员函数

常函数

成员函数后加const修饰就是常函数void example() const{},常函数的特点是不能修改成员变量,只能读取成员变量。不可修改成员属性。成员属性声明时加关键字mutable后,在常函数中依然可以修改。

常对象

声明对象前加const称该对象为常对象,常函数只能调用常函数,常对象只能调用常函数。

//2-7-5
#include<iostream>
using namespace std;
class example
{
    public:
    example()
    {
        a=0;
    }
    int a;
    example& func(int a)
    {
        this->a=a;
        return *this;
    }
    void print() const
    {
        cout<<a<<endl;
    }
    //void newfunc(int a) const
    //{
        //this->a=a;常函数不能修改成员变量
        //func(int a);常函数不能调用非常函数

    //}
};
int main()
{
    example ex;
    ex.func(10).func(20);
    ex.print();
    cout<<ex.a<<endl;
    const example ex2;
    //ex2.func(10);常对象只能调用常函数
    ex2.print();
}

友元

友元分为两种:全局函数做友元,类做友元。类做友元的时候,可以分为成员函数做友元,成员变量做友元。

在程序中,有时候需要访问类的私有成员,这时候就需要用到友元。友元的目的是为了访问类的私有成员。

以下是一个例子:

//2-8-1
#include<iostream>
using namespace std;
class example
{
    friend void goodprint(example &ex);
    public:
    example(int a,int b)
    {
        this->a=a;
        this->b=b;
    }

    private:
    int a;
    int b;
};
void goodprint(example &ex)
{
    cout<<ex.a<<endl;
    cout<<ex.b<<endl;
}
int main()
{
    example ex(10,20);
    goodprint(ex);
}

如果不加friend,就会因为权限问题,不可访问私有成员。

类做友元:

//2-8-2
#include<iostream>
using namespace std;
class example
{
    friend class example2;
    public:
    example(int a,int b)
    {
        this->a=a;
        this->b=b;
    }

    private:
    int a;
    int b;
};
class example2
{
    public:
    void print(example *ex)
    {
        cout<<ex->a<<endl;
        cout<<ex->b<<endl;
    }
};
int main()
{
    example ex(10,20);
    example2 ex2;
    ex2.print(&ex);
}

成员函数做友元:

//2-8-3
#include<iostream>
using namespace std;
class example2;
class example
{
    public:
    example();
    void print();
    private:
    example2 *ex;
};
class example2
{
    public:
    friend void example::print();
    example2()
    {
        a = 10;
        b = 20;
    }
    example2(int a, int b)
    {
        this->a = a;
        this->b = b;
    }
    private:
    int a;
    int b;
};
example::example()
{
    ex = new example2;
}
void example::print()
    {
        cout<<ex->a<<endl;
        cout<<ex->b<<endl;
    }
int main()
{
    example2 ex(100,20);
    example ex2;
    ex2.print();
    return 0;
}
喜欢就支持一下吧
点赞 0 分享 收藏
评论 抢沙发
OωO
取消