一、方法定义和实现分开
-
将声明与实现分离,代码会有更好的可读性,不是必须的
-
选择项目
Class View,右键新建Class;在xxx.h头文件中定义类,且只声明成员方法:struct Person{ int x; void setx(int x); int getx(); }; -
,在xxx.cpp中实现方法:(但是要告诉编译器,这不是一个普通的函数,而是Person类中的成员方法)
void Person::setx(int x){ this->x = x; } int Person::getx(){ return this->x; } -
最后在要使用Person类中成员的cpp中include xxx.h引用头文件,就可以使用xxx.h中类创建对象,使用其属性和方法
#include "stdafx.h" #include "MyClass.h" int main(int argc, char* argv[]){ Person p; p.setx(1); printf("%d\n",p.getx()); return 0; } -
特别说明:
- xxx.h只是一个文件,头文件可以是任何的后缀名,不一定是.h,比如可以叫xxx.exe
- #include 的作用只是把里面的内容复制过来,仅此而已
- xxx.h 与 xxx.cpp并不要求一定同名
二、public和private
1.public权限说明
- public权限:这个成员(属性、方法等)哪里都可以用,所以对外提供的函数或者变量,发布成public的
- public/private可以修饰函数也可以修饰变量
- 注意:目前阶段,类的构造器只能设置成public。后面学习设计模式时定义成private也有办法使用。
2.private权限说明
-
private权限:这个成员只用于类内部使用,即只有结构体内部的函数才可以访问private的成员,不能在其他的地方使用,所以不对外公布的,发布成private
-
一般来说类的成员变量不能让别人轻易改动,如果要改动,也必须要对修改的值进行判断检验是否合法,所以一般都会对外发布可以修改或打印私有成员变量的方法,在方法中检验修改是否合法:
#include "stdafx.h" struct Person{ private: //私有成员变量 int age; public: //共有成员方法 void SetAge(int age){ if(age > 0 && age <= 100){ this->age = age; //private成员变量只有类中的其他成员可以访问 } } int GetAge(){ return age; } }; int main(int argc, char* argv[]){ Person p; //不能p.age = 18; p.SetAge(18); printf("%d\n",p.GetAge()); return 0; }
1)private成员分配空间
-
当创建一个类的对象时,不管是公有变量还是私有变量,编译器分配空间时都一视同仁,还是会分配空间,只不过我们要使用私有变量时,编译器是不允许的
#include "stdafx.h" struct Person{ private: int x; int y; public: int z; void Init(int x,int y,int z){ this->x = x; this->y = y; this->z = z; } }; int main(int argc, char* argv[]){ Person p; p.Init(1,2,3); printf("%d\n",sizeof(p)); //12,从这里也可以发现,不管私有还是公有成员变量,都会为其分配空间 return 0; }查看反汇编发现:创建p对象后,最后一个参数就是对象的首地址,所以ebp-0xC也是成员x的地址,存到ecx寄存器中;接着进入到函数内部,ecx中就是x的地址(即对象首地址),然后把x的地址值存入到ebp-4,接着又把地址值存入到eax,所以
mov dword ptr [eax],ecx就是在给成员x赋值;接着又把x的地址值存入到edx,所以[edx+4]中存的就是y;后面以此类推。还可以通过栈窗口发现,x,y,z成员就是挨着存的,看不出来哪一个是private哪一个是public
2)private成员变量其实可以访问
-
前面讲过,不管是private成员变量还是public成员变量,在内存中都是一视同仁,就存储在对象的内存空间中,所以可以用指针访问即可
#include "stdafx.h" struct Person{ private: int x; int y; public: int z; void Init(int x,int y,int z){ this->x = x; this->y = y; this->z = z; } }; int main(int argc, char* argv[]){ Person p; p.Init(1,2,3); int* pp = (int*)&p; //定义一个int*指针,访问x,y,z的值即可 printf("%d %d %d\n",*pp,*(pp + 1),*(pp + 2)); //1 2 3 return 0; } -
所以再次印证了:private修饰的成员与普通的成员没有区别 只是编译器会检测
三、class和struct区别
-
编译器默认class中的成员为private,而struct中的成员为public
-
继承中的区别:
-
如果一个子类继承一个父类时,没有声明以什么方式继承,默认以private的方式继承,即继承(复制)过来的成员都是私有的!
#include "stdafx.h" class Person{ private: int x; int y; public: int z; void Init(int x,int y,int z){ this->x = x; this->y = y; this->z = z; } }; class Student:Person{ //由于这里没有声明以什么方式继承,默认以private方式继承 private: int m; public: void changeZ(){ //z = 10; //因为以private方式继承,即使父类中的z是public,但是继承来后就变成private //x = 1; //x本来就是私有的,当然使用不了 } }; int main(int argc, char* argv[]){ return 0; } -
如果子类中想使用父类中的public的变量或方法,就需要声明以public的方式继承
class Student:public Person{ //以public方式继承 private: int m; public: void changeZ(){ z = 10; //因为以public方式继承,所以可以使用父类中public的成员 //x = 1; //x本来就是私有的,当然使用不了 } }; -
但是注意:父类中的私有成员是会被继承的,即还是会为私有成员变量分配空间,只是子类中无法使用父类的私有成员变量(所以说嘛,子类对象想访问父类中的私有成员变量,也是有办法的,和上面一样)
#include "stdafx.h" class Person{ private: int x; int y; public: int z; Person(){ this->x = 1; this->y = 2; this->z = 3; } }; class Student:public Person{ private: int m; public: void changeZ(){ m = 4; } }; int main(int argc, char* argv[]){ Student stu; //创建子类对象时,是会先调用父类的构造器的!所以x,y,z才会被赋值1,2,3 stu.changeZ(); int* stup = (int*)&stu; printf("%d\n",sizeof(stu)); //16,说明父类中无论私有公有的成员变量都被继承过来了 printf("%d %d %d %d\n",*(stup),*(stup + 1),*(stup + 2),*(stup + 3)); //1 2 3 4 return 0; }
-
四、作业
1.class和private练习
-
将上一节课的所有练习改为class实现,并添加private/public进行权限控制,而且将类的定义与实现分开来写:定义写到xxx.h中,函数实现写在xxx.cpp中
-
在MyClass.h中声明DataInfo类,TimeInfo类:
#if !defined(AFX_MYCLASS_H__44CA5D47_B224_42F2_A26E_CAD8CD157CD1__INCLUDED_) #define AFX_MYCLASS_H__44CA5D47_B224_42F2_A26E_CAD8CD157CD1__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class DataInfo{ private: int year; int month; int day; public: DataInfo(int year,int month,int day){ this->year = year; this->month = month; this->day = day; } DataInfo(){ year = 2015; month = 4; day = 2; } void SetDay(int day); int GetDay(); void SetYear(int year); int GetYear(); void SetMonth(int month); int GetMonth(); }; class TimeInfo:public DataInfo{ private: int hour; int minute; int second; public: void SetHour(int hour); void SetMinute(int minute); void SetSecond(int second); int GetHour(); int GetMinute(); int GetSecond(); }; #endif // !defined(AFX_MYCLASS_H__44CA5D47_B224_42F2_A26E_CAD8CD157CD1__INCLUDED_)
-
在MyClass.cpp中实现方法:
#include "stdafx.h" #include "MyClass.h" void DataInfo::SetDay(int day){ this->day = day; } int DataInfo::GetDay(){ return day; } void DataInfo::SetYear(int year){ this->year = year; } int DataInfo::GetYear(){ return year; } void DataInfo::SetMonth(int month){ this->month = month; } int DataInfo::GetMonth(){ return month; } void TimeInfo::SetHour(int hour){ this->hour = hour; } void TimeInfo::SetMinute(int minute){ this->minute = minute; } void TimeInfo::SetSecond(int second){ this->second = second; } int TimeInfo::GetHour(){ return hour; } int TimeInfo::GetMinute(){ return minute; } int TimeInfo::GetSecond(){ return second; }
-
最后在要使用的cpp中包含MyClass头文件,创建对象并使用成员方法打印日期:
#include "stdafx.h" #include "MyClass.h" void Test(){ //访问TimeInfo对象的成员 TimeInfo t; t.SetHour(21); t.SetMinute(8); t.SetSecond(52); printf("%04d.%02d.%02d - %02d:%02d:%02d\n",t.GetYear(),t.GetMonth(),t.GetDay(),t.GetHour(),t.GetMinute(),t.GetSecond()); } int main(int argc, char* argv[]){ Test(); return 0; }
文章介绍了C++中将类的声明与实现分开的方法,强调了这样做对代码可读性的提升。同时,详细阐述了public和private权限的区别,public成员可以在任何地方使用,而private成员仅限类内部访问。文章还讨论了类的构造器默认为public以及如何通过指针访问private成员。此外,提到了class和struct在默认访问权限上的差异,并给出了相关示例。

2622

被折叠的 条评论
为什么被折叠?



