深入理解C++中 class的成员变量,和成员函数

下文的第一段代码块中给出了一个普通的类Dog的实现,有私有成员dId,有bark()成员函数描述dog的行为。bark中有使用到成员dId。

在main函数中打印了Dog的大小4byte,可以想见它只存储了成员dId,成员函数并没有包括在类Dog中。然后是bark的普通通访问方式,创建对象,通过.访问。

之后创建了一个函数指针barkptr,它无返回值,有一个形参Dog*,可以看出barkptr和Dog::bark唯一的区别就是多了个形参Dog*,巧合的是正好bark可以赋值给barkptr,并且我们通过给barkptr传递一个Dog对象tyke的指针还能访问到bark函数,且bark函数还能访问到tyke的私有成员dId。

#include <iostream>
//Dog是个普通的类
class Dog{
private:
	int dId;

public:
	Dog(int id) : dId(id){}

	void bark(){
		std::cout << "I am NO." << dId << ",\tbark! bark!" << std::endl;
	}
};

int main(){
	std::cout << "sizeof Dog: " << sizeof(Dog) << std::endl;
	//普通访问
	Dog spike(100);
	spike.bark();
    
    //获取Dog中成员函数bark的函数指针
	void(*barkptr)(Dog*) = ( void(*)(Dog *) )&Dog::bark;
	//通过this指针访问
	Dog tyke(101);
	barkptr(&tyke);
}

//执行结果
sizeof Dog: 4
I am NO.100,    bark! bark!
I am NO.101,    bark! bark!

正是因为,C++中对类成员的存储其实类似于C中的结构体,将一组数据成员按序排在一起(这个过程中考虑字节对齐)。而至于对成员函数的存储就类似于C中的普通函数,只是隐式的在成员函数中添加了一个结构体指针,指向数据成员。正数因为这样,上边的访问方式才得以实现。可以看出,C++中的类,其实只是在C的结构体和函数的基础上的少许变更,在加上C++新发明的作用域的概念而实现的。

下文是利用C语言的结构体、全局函数和namespace对C++中类的示意说明。当然从结构体到类远没有这么简单,但我们至少能理清C++类中的成员和成员函数,和C中的什么是相似相对应的。

#include<stdio.h>

namespace Dogc
{
    typedef struct
    {
        int dId;
    }Dogc;

    void bark(Dogc *this_ptr)
    {
        printf("I am NO.%d,\tbark! bark!\n", this_ptr->dId);
    }
}

int main(){
    std::cout << "sizeof Dogc: " << sizeof(Dogc) << std::endl;
    Dogc tykec;
    tykec.dId = 12580;
    bark(&tykec);
    return 0;
}
#C++#
全部评论

相关推荐

04-05 21:13
邯郸学院 Java
点赞 评论 收藏
分享
评论
2
4
分享

创作者周榜

更多
牛客网
牛客企业服务