小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
一、类和对象
1.1 类和对象的基本使用
1.1.1 类和对象的简单使用
类和结构体唯一的区别就是默认的成员权限不一样,类默认的权限是私有的,结构体默认的权限是公有的
C++类中或者结构体中成员的访问权限:
- public:公有权限,类内和类外都可以直接操作
- 将类中的变量称之为成员变量,成员数据
- 将类中的函数称之为成员函数
- private:私有权限,类内可以直接操作,类外不可以直接操作
- protected:受保护的权限,如果不涉及继承,跟private一样的
类实例化对象,就是类定义的变量
#include <iostream>
using namespace std;
//定义一个类
class Person
{
public:
//将类中的变量称之为成员变量,成员数据
int id;
string name;
char sex;
int score;
//将类中的函数称之为成员函数
void GetMsg()
{
cout << id << " " << name << " ";
cout << sex << " " << score << endl;
}
};
int main()
{
//类实例化对象,就是类定义的变量
Person p1;
p1.id = 1001;
p1.name = "张三";
p1.sex = 'M';
p1.score = 90;
p1.GetMsg();
return 0;
}
1.1.2 类的大小
- 类所占空间大小
- 空类占一个字节
- ==成员函数不占类的空间==(因为同一个函数实例化的不同对象使用的是这个函数的空间,这样做是为了节省空间)
- 类空间的计算与结构体一样
#include <iostream>
using namespace std;
class C1{
public:
int a;
private:
char b;
protected:
short c;
};
class C2{
int a;
char b;
//成员函数不占类的空间
void fun()
{
cout << "hello world" << endl;
}
};
class C3{
};
void test1()
{
cout << "sizeof(C1) = " << sizeof(C1) << endl;
cout << "sizeof(C2) = " << sizeof(C2) << endl;
cout << "sizeof(C3) = " << sizeof(C3) << endl;
}
int main()
{
test1();
return 0;
}
sizeof(C1) = 8
sizeof(C2) = 8
sizeof(C3) = 1
1.2 类中私有成员的操作方法
类中成员的访问权限很大程度上就是为了保护类中的成员不被其他程序所操作,起到保护作用,所以一般成员变量都会设置为私有的,这样做就不会让实例化的对象直接操作。
==私有成员的操作方法==:
- 类内定义公有的成员函数来操作
- 友元
#include <iostream>
using namespace std;
//私有成员通过公有的成员函数操作
class Person{
public:
void setId(int id)
{
p_id = id;
}
int getId()
{
return p_id;
}
void setName(string name)
{
p_name = name;
}
string getName()
{
return p_name;
}
void setSex(char sex)
{
p_sex = sex;
}
char getSex()
{
return p_sex;
}
void setScore(int score)
{
p_score = score;
}
int getScore()
{
return p_score;
}
void printMsg()
{
cout << p_id << ", ";
cout << p_name << ", ";
cout << p_sex << ", ";
cout << p_score << endl;
}
private:
int p_id;
string p_name;
char p_sex;
int p_score;
};
int main()
{
Person p1;
p1.setId(1001);
p1.setName("张三");
p1.setSex('M');
p1.setScore(100);
cout << p1.getId() << endl;
cout << p1.getName() << endl;
cout << p1.getSex() << endl;
cout << p1.getScore() << endl;
p1.printMsg();
return 0;
}
1.3 练习:立方体求值
设计立方体类(Cube),求出立方体的面积( 2ab + 2ac + 2bc )和体积( a * b * c),并判断两个立方体是否相等。
要求:
- 私有成员变量:长length、宽wide、高hight
- 成员函数:求面积area、求体积volume等
- 全局函数:判断两个立方体是否相等
#include <iostream>
using namespace std;
class Cube{
public:
void setValue(int length, int wide, int hight)
{
mylength = length;
mywide = wide;
myhight = hight;
}
//求面积
int getArea()
{
int myarea = 2*mylength*mywide + 2*mylength*myhight + 2*mywide*myhight;
return myarea;
}
//求体积
int getVolume()
{
return mylength*mywide*myhight;
}
int getLength()
{
return mylength;
}
int getWide()
{
return mywide;
}
int getHight()
{
return myhight;
}
private:
int mylength;
int mywide;
int myhight;
};
bool cubeIsEqu(Cube c1, Cube c2)
{
if(c1.getLength() == c2.getLength() && c1.getWide() == c2.getWide() && c1.getHight() == c2.getHight())
{
return true;
}
else
{
return false;
}
}
int main()
{
Cube c1;
c1.setValue(10, 8, 6);
cout << "面积:" << c1.getArea() << endl;
cout << "体积:" << c1.getVolume() << endl;
Cube c2;
c2.setValue(10, 8, 6);
cout << "面积:" << c2.getArea() << endl;
cout << "体积:" << c2.getVolume() << endl;
if(cubeIsEqu(c1, c2))
{
cout << "相等" << endl;
}
else
{
cout << "不相等" << endl;
}
return 0;
}
1.4 涉及类的分文件编程
1.4.1 创建文件创建类
第一步:在当前工程的位置鼠标右键点击“add new”
第二步:在弹出的对话框中选择“C++”中的“C++ Class”,可以创建.cpp和.h
第三步:设置类的名字
第四步:点击下一步即可完成创建
1.4.2 多文件编程
cude.h
Cube();
Cube::Cube()
{
}
#ifndef CUBE_H
#define CUBE_H
#include <iostream>
using namespace std;
class Cube
{
public:
Cube();
//成员函数类内声明,类外实现
void setValue(int length, int wide, int hight);
//求面积
int getArea();
//求体积
int getVolume();
int getLength();
int getWide();
int getHight();
private:
int mylength;
int mywide;
int myhight;
};
bool cubeIsEqu(Cube c1, Cube c2);
#endif // CUBE_H
cude.cpp
#include "cube.h"
Cube::Cube()
{
}
//成员函数类外实现的时候,函数名需要类名通过域解析符访问
void Cube::setValue(int length, int wide, int hight)
{
mylength = length;
mywide = wide;
myhight = hight;
}
//求面积
int Cube::getArea()
{
int myarea = 2*mylength*mywide + 2*mylength*myhight + 2*mywide*myhight;
return myarea;
}
//求体积
int Cube::getVolume()
{
return mylength*mywide*myhight;
}
int Cube::getLength()
{
return mylength;
}
int Cube::getWide()
{
return mywide;
}
int Cube::getHight()
{
return myhight;
}
bool cubeIsEqu(Cube c1, Cube c2)
{
if(c1.getLength() == c2.getLength() && c1.getWide() == c2.getWide() && c1.getHight() == c2.getHight())
{
return true;
}
else
{
return false;
}
}
main.cpp
#include <iostream>
#include "cube.h"
using namespace std;
//多文件编程
int main()
{
Cube c1;
c1.setValue(10, 8, 6);
cout << "面积:" << c1.getArea() << endl;
cout << "体积:" << c1.getVolume() << endl;
Cube c2;
c2.setValue(10, 8, 6);
cout << "面积:" << c2.getArea() << endl;
cout << "体积:" << c2.getVolume() << endl;
if(cubeIsEqu(c1, c2))
{
cout << "相等" << endl;
}
else
{
cout << "不相等" << endl;
}
return 0;
}
1.5 对象初始化和相互赋值问题
==看注释==
#include <iostream>
#include <string.h>
using namespace std;
class Cube{
public:
//成员函数类内声明,类外实现
void setValue(int length, int wide, int hight);
//求面积
int getArea();
//求体积
int getVolume();
int getLength();
int getWide();
int getHight();
void printMsg()
{
cout << "长:" << mylength << ", ";
cout << "宽:" << mywide << ", ";
cout << "高:" << myhight << endl;
}
private:
int mylength;
int mywide;
int myhight;
};
//成员函数类外实现的时候,函数名需要类名通过域解析符访问
void Cube::setValue(int length, int wide, int hight)
{
mylength = length;
mywide = wide;
myhight = hight;
}
//求面积
int Cube::getArea()
{
int myarea = 2*mylength*mywide + 2*mylength*myhight + 2*mywide*myhight;
return myarea;
}
//求体积
int Cube::getVolume()
{
return mylength*mywide*myhight;
}
int Cube::getLength()
{
return mylength;
}
int Cube::getWide()
{
return mywide;
}
int Cube::getHight()
{
return myhight;
}
bool cubeIsEqu(Cube c1, Cube c2)
{
if(c1.getLength() == c2.getLength() && c1.getWide() == c2.getWide() && c1.getHight() == c2.getHight())
{
return true;
}
else
{
return false;
}
}
//类实例化的对象的初始化和相互赋值
void test1()
{
//如果成员变量是公有的权限,可以初始化,
//但是如果成员变量是私有的权限,无法初始化
//Cube c1 = {10, 8, 6};
//cout << "面积:" << c1.getArea() << endl;
//cout << "体积:" << c1.getVolume() << endl;
Cube c1;
c1.setValue(10, 8, 6);
c1.printMsg();
//注意:C++中对象之间赋值有很大区别
//实例化一个对象的同时同另一个对象赋值与
//实例化对象之后再赋值意思完全不一样
//实例化对象的同时赋值调用的是拷贝构造函数
//c2 = c1本质就是值传递
//c2.mylength = c1.mylength
//c2.mywide = c1.mywide
//c2.myhight = c1.myhight
//但是如果现在类中有一个成员变量是指针变量,可能需要
//在堆区开辟空间,例如char *name
//所以c1里面要给name分配空间name = new char[32];
//如果c2 = c1按照值传递的思想,那么
//c2.name = c1.name,就会导致c1和c2的name保存同一块地址,
//如果是这样就会导致当对象操作完毕后要释放堆区空间时,
//会释放两次,就会报错,我们将这种情况称之为浅拷贝,
//与之相反的称之为深拷贝
Cube c2 = c1;
c2.printMsg();
//实例化对象之后赋值调用的是运算符=的重载函数
Cube c3;
c3 = c1;
c3.printMsg();
}