对象:万事万物皆为对象;
类:具有相同性质的对象,可以抽象为类。
(1)将属性和行为作为一个整体,表现生活中的事物。
(2)将属性和行为加以权限控制。
注:叫法:
类中的属性和行为:统称成员
属性:又称为 成员属性、成员变量
行为:又称为 成员函数、成员方法
class 类名 {?访问权限 :属性 / 行为 } ;
实例化:通过一个类,创建出一个对象。
例:设计一个圆类,求圆的周长:
//设计一个圆类,求圆的周长
const double PI = 3.14;
class Circle
{
//访问权限
public:
//属性
int r;
//行为
double C()
{
return 2 * PI * r;
}
};
int main()
{
Circle round;//实例化
round.r = 10;
cout << "圆的周长:" << round.C() << endl;
return 0;
}
公共权限(public):类内可以访问,类外可以访问
保护权限(protected):?类内可以访问,类外不可以访问,子类可访问父类中保护内容
私有权限(private):?类内可以访问,类外不可以访问,子类不可访问父类中私有内容
(保护和私有在继承中有区别)
例:
class Person
{
public:
string Name;
protected:
string car;
private:
int Password;
public:
void func()
{
Name = "name";
car = "car";
Password = 1;//类内均可访问
}
};
int main()
{
Person p1;
p1.Name = "zhangsan";
p1.car = "benchi";//报错,保护和私有访问不到
return 0;
}
基本一致,但默认的访问权限不同。
struct的默认权限为公共,而class的默认权限为私有。
(默认权限,即未标明访问权限时,创建成员时的成员权限)
将成员属性设为私有,提供公共的函数来读写私有成员。
优点:
1.可以自己控制读写权限;
2.对于写,可以检测数据有效性
//人类
class Person
{
public:
//设置姓名
void setName(string name)
{
m_Name = name;
}
//获取姓名
string getName()
{
return m_Name;
}
//获取年龄
int getAge()
{
return m_Age;
}
//设置偶像
void setIdol(string Idol)
{
m_Idol = Idol;
}
//设置年龄
void setAge(int Age)
{
if (Age < 0 || Age>150)
{
cout << "年龄有误,写入失败" << endl;
return;
}
m_Age = Age;
}
private:
string m_Name;//姓名 可读可写
int m_Age = 18;//年龄 可读 也可以写但只限制在0到100(检测数据有效性)
string m_Idol;//偶像 只写
};
构造函数:为对象的成员属性赋值。
析构函数:对象销毁前进行清理。
c++利用这两个函数进行对象的初始化和清理,必须有,如果程序员不实现,会由编译器自动实现,但是是空实现。(即函数中没有内容)
注:构造函数和析构函数应放在public里。
1.没有返回值也不写void;
2.函数名称与类名相同;
3.构造函数可以有参数,因此可以重载;
4.构造函数会由编译器自动调用,无需手动调用。
1.没有返回值也不写void;
2.函数名称与类名相同,前加 ~;
3.构造函数不可以有参数,因此不可以重载;
4.构造函数会由编译器自动调用,无需手动调用。
两种分类方式:
按参数分类:有参构造和无参构造
按类型分类:普通构造和拷贝构造
三种调用方式:
括号法,显示法,隐式转换法。
Person()
{
cout << "构造函数的调用" << endl;
}
Person(int a)
{
cout << "构造函数的调用" << endl;
}
传入一个对应类的引用,同时必须加const。
Person(const Person &p)
{
age = p.age;
}
用括号传参的方式决定用哪一种构造函数。
//括号法
Person p1;//默认无参构造
Person p2(10);//有参构造
Person p3(p2);//引用构造
注:用无参构造时不要加(),编译器会默认为函数声明,而非创建对象。
//显示法
Person p1;
Person p2 = Person(10);//有参构造
Person p3 = Person(p2);//拷贝构造
注:1.匿名对象,?会在本行执行后就被回收掉。
Person(10);
2.不要利用拷贝构造函数初始化匿名对象,因为会被认为是一个对象的声明,重定义报错。
Person(p3);
//隐式转换法
Person p4 = 10;
Person p5 = p4;
1.使用一个已经创建完毕的对象来初始化一个新对象
void test01()
{
Person p1(10);
Person p2(p1);
}
2.值传递的方式给函数参数传值
void work(Person p)//拷贝构造
{
}
void test02()
{
Person p;
work(p);
}
1.默认情况下,c++编译器至少给一个类添加3个函数:
(1)默认构造函数(无参,函数体为空)
(2)默认析构函数(无参,函数体为空)
(3)默认拷贝构造函数,对属性进行值拷贝(即不写拷贝构造函数也有默认的)
2.如果写了有参构造函数,编译器就不再提供默认构造函数,但依然有拷贝构造。
? 如果写了拷贝构造函数,编译器就不提供其他普通构造函数了。
无参 < 有参 < 拷贝
class Person
{
public:
Person(int a)
{
cout << "Person有参构造函数调用" << endl;
}
~Person()
{
cout << "Person析构函数调用" << endl;
}
int m_age;
};
int main()
{
Person p;//报错,不再有默认构造函数
return 0;
}
?