看下面这个代码;
class people
{
char* name;
char* sex;
int age;
};
class就是类的关键字。people就是这个类的名字,{}为类的主体,里面有成员,变量叫做成员变量,函数叫做成员函数。
c语言中的struct
也可以作为类的关键字。只不过在c++中最好使用c++的class写法。
struct people
{
void print()
{
cout << "hello world\n";
}
int age;
char name[20];
};
类的定义有两种形式:
一种是成员函数的声明和定义都在类的里面。
另一种是类的里面是成员函数的声明,在另一个文件中实现类的定义。
类的限定符有:public(公有) protected(保护) private(私有)
公有就是别人是可以访问的,
私有就是别人不可以访问的。
对于class的类默认访问权限是private。
对于struct的类默认访问权限是public。
struct people
{
int age;
char name[20];
};
class p
{
char* name;
char* sex;
int age;
};
int main()
{
people a;
a.age;//这个可以访问
//p b;
//b.age;//这个就不可以访问
return 0;
}
我们在实现类的时候,想给别人使用的就用public限定成共有的。不想让别人使用的就限制成私有的。
class p
{
public:
void print()
{
cout << "hello world\n";
}
private:
char* name;
char* sex;
int age;
};
类定义了新的定义域,里面的成员都属于该作用域。当在类的外面定义成员函数的时候,需要说明该成员的作用域。
class p
{
public:
void print();
private:
char* name;
char* sex;
int age;
};
void p::print()
{
cout << "hello world\n";
}
实现了一个类,当这个类没有创建对象的时候,它在内存中是没有开辟空间的。
类的实例化也就是用类创建对象。
类的大小是怎么计算的呢?
类的大小只需要计算成员变量的大小(计算方法和c语言的一样)。
当类为空的时候,大小为1字节,只是为了占位。
class Test
{};
int main()
{
std::cout << sizeof(Test) <<std::endl;
return 0;
}
而成员函数是放在公共代码区的,并不是在成员里面。
class P
{
public:
void Print()
{
cout << "haha" << endl;
}
};
int main()
{
P* ptr = nullptr;
ptr->Print();
return 0;
}
该程序照样是可以运行的。在第13行的时候,编译的时候根本就没有解引用去找成员,而是直接去公共代码区去找的该函数的地址。
从下面编译的结果可以看出:
看下面这个代码:
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << ' '<<_month <<' '<< _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date a, b;
a.Init(1, 1, 1);
b.Init(2, 2, 2);
a.Print();
b.Print();
return 0;
}
程序是怎么判断Init,Print是各自属于哪一个对象的?
其实有一个this指针,C++编译器在非静态成员函数增加了隐形的指针参数,调用函数的时候其实把对象的地址传递给了this指针。
this指针是编译的时候程序自己添加的,不需要我们自己手动添加。
1.this指针的类型是类的类型*const
。
2.this不能在参数中显示,但是可以在函数体中的成员变量中可以使用。
3.this是成员函数的第一个隐形参数,存在栈区,因为是形参,具体存在哪里取决于编译器,不需要用户自己传递。
看下面这个代码:Print1就可以正常的运行,而Print2并不能,就是因为Print2需要对空指针解引用。编译的时候不会出错,因为不会去类中去找这个函数。
class Date
{
public:
void Print1()
{
cout << "Print1()" << endl;
}
void Print2()
{
cout << _year << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date* a = nullptr;
a->Print1();
a->Print2();
return 0;
}