| 访问属性 | 属性 | 对象内部 | 对象外部 |
|---|---|---|---|
| public | 公有 | 可访问 | 可访问 |
| protected | 保护 | 可访问 | 不可访问 |
| private | 私有 | 可访问 | 不可访问 |
在没有涉及继承与派生时,protected与private 是同等级的,外部不允许访问。
#include
#include
using namespace std;
class Person{
private:
char name[20];//定义类的时候,不要给成员初始化
int age;
public:
void setNmae(char* n){
strcpy(name,n);
}
char* getName(){
return name;
}
void setAge(int a){
age = a;
}
int getAge(){
return age;
}
};
int main(int argc, char *argv[])
{
Person person;
char name[20] = "tony";
person.setNmae(name);
person.setAge(15);
cout << person.getName() << person.getAge() << endl;
return 0;
}
实例:设计一个点和圆的类
#include
using namespace std;
class Point{//设计一个点的类
private:
int m_x;
int m_y;
public:
void setX(int x){
m_x = x;
}
int getX(){
return m_x;
}
void setY(int y){
m_y = y;
}
int getY(){
return m_y;
}
};
class Circle{//设计一个圆的类
private:
Point point;
int r;
public:
void setPoint(int x,int y){
point.setX(x);
point.setY(y);
}
void setR(int x){
r = x;
}
void isPointOnCircle(Point &ob){
//判断点与圆的关系
int distance = (point.getX()-ob.getX()) *(point.getX()-ob.getX()) + (point.getY() - ob.getY()) * (point.getY() - ob.getY());
if(distance > r*r){
cout << "在圆外" << endl;
}else if(distance == r*r){
cout << "在圆上" << endl;
}else{
cout << "在圆内" << endl;
}
}
};
int main(int argc, char *argv[])
{
//实例化一个点对象
Point p1;
p1.setX(5);
p1.setY(5);
//实例化一个圆对象
Circle circle;
circle.setR(3);
circle.setPoint(3,3);
//判断点point与圆的关系
circle.isPointOnCircle(p1);
return 0;
}
成员数据占类的空间大小,成员函数不占类空间的大小。
using namespace std;
class Data
{
private:
//成员数据 占类的空间大小
int num;//4B
public:
//成员函数 不占类的空间大小
void setNum(int data)
{
num = data;
}
int getNum(void)
{
return num;
}
};
void test01()
{
printf("%d\n",sizeof(Data));//4B
}
class data{
private:
int num;
public:
void setNum(int x);
int getNum();
};
void Data::setNum(int x){
num = x;
}
int Data::getNum(){
return num;
}
void test01(){
Data data;
data.setNum(100);
cout << data.getNum() << endl;
}
int main(int argc, char *argv[]){
test01();
return 0;
}
data1.h
#ifndef DATA1_H
#define DATA1_H
class Data1
{
private:
int num;
public:
void setNum(int x);
int getNum();
};
#endif // DATA1_H
data1.cpp
#include "data1.h"
void Data1::setNum(int x){
num = x;
}
int Data1::getNum(){
return num;
}
main.cpp
#include
#include"data1.h"
using namespace std;
void test01(){
Data1 data;
data.setNum(1000);
cout << data.getNum() << endl;
}
int main(int argc, char *argv[]){
test01();
return 0;
}
构造函数和析构函数都会被编译器自动调用,构造函数完成对象的初始化动作,析构函数在对象结束的时候完成清理工作。
注意:初始化和清理工作是编译器强制我们做的事情,即使程序并没有提供初始化操作和清理操作,编译器也会给程序增加默认的操作,但是默认操作并不会做任何事。
构造函数:实例化对象的时候系统自动调用
析构函数:对象释放的时候系统自动调用
构造函数的语法:
构造函数名与类名相同,没有返回类型,连void都不可以,但可以有参数,可以重载。
析构函数的语法:
析构函数的名字是在类名前面加“ ~ ”组成,没有返回类型,连void都不可以,不能有参数,不能重载。
案例:
#include
using namespace std;
class Data
{
public:
Data() {
cout << "无参构造函数" << endl;
}
Data(int num){
num = 100;
cout << "有参构造函数" << endl;
}
~Data(){
cout << "析构函数" << endl;
}
};
int main(int argc, char *argv[])
{
cout << "-----------01----------" << endl;
Data ob;
cout << "-----------02----------" << endl;
return 0;
}
按参数类型分类: 分为无参构造函数和有参构造函数
按类型分类:普通构造函数和拷贝构造函数(复制构造函数)
#include
using namespace std;
class Data
{
private:
int num;
public:
Data() {
num = 0;
cout << "无参构造函数" << endl;
}
Data(int num1){
num = num1;
cout << "有参构造函数" << num << endl;
}
~Data(){
cout << "析构函数" << num << endl;
}
};
void test01(){
//调用无参或默认构造函数
Data ob;
//调用有参构造函数(显式调用)
Data ob1 = Data(100);
//调用有参构造函数(隐式调用)
Data ob2(1000);
//隐式转换的方式 调用有参构造(针对于 只有一个数据成员)(尽量别用)
Data ob3 = 10000;//转化成Data ob5(30)
//匿名对象(当前语句结束 匿名对象立即释放)
Data(40);
cout << "---------------------" << endl;
//千万不要 用以下方式调用 无参构造
//Data ob4();//不会被认为时实例化对象,会被看作函数ob4的声明
}
int main(int argc, char *argv[])
{
cout << "-----------01----------" << endl;
test01();
cout << "-----------02----------" << endl;
return 0;
}

注意:在同一作用域,构造和析构的顺序相反(类似于栈,先进后出)
#include
using namespace std;
class Data
{
public:
int num;
public:
Data() {
num = 0;
cout << "无参构造函数" << endl;
}
Data(int num1){
num = num1;
cout << "有参构造函数" << num << endl;
}
//拷贝构造函数
Data(const Data &ob){//Data &ob = ob5;
num = ob.num;
cout << "拷贝构造函数" <<endl;
}
~Data(){
cout << "析构函数" << num << endl;
}
};
void test01(){
//调用有参构造函数(隐式调用)
Data ob3 = Data(100);
cout<<"ob3.num = "<<ob3.num<<endl;
//显式调用拷贝构造函数
Data ob5 = Data(ob3);
cout<<"ob5.num = "<<ob5.num<<endl;
//隐式调用拷贝构造函数
Data ob6(ob3);
cout<<"ob6.num = "<<ob6.num<<endl;
//隐式转换调用拷贝构造函数
Data ob7 = ob3;
cout<<"ob6.num = "<<ob6.num<<endl;
}
int main(int argc, char *argv[])
{
cout << "-----------01----------" << endl;
test01();
cout << "-----------02----------" << endl;
return 0;
}
记住一句话:旧对象初始化新对象才会调用拷贝构造函数
Data ob1(10);
Data ob2(ob1);//拷贝构造
Data ob3 = Data(ob1);//拷贝构造
Data ob4 = ob1;//拷贝构造函数
注意:下方就不会调用拷贝构造
Data ob1(10);
Data ob2;
ob2 = ob1;//不会调用拷贝构造 单纯对象 赋值操作
案例:
void test02(){
Data ob1 = Data(100);
Data ob2;
ob2 = ob1;
cout<<"ob1.num = "<<ob1.num<<endl;
cout<<"ob2.num = "<<ob2.num<<endl;
}
int main(int argc, char *argv[])
{
cout << "-----------01----------" << endl;
test02();
cout << "-----------02----------" << endl;
return 0;
}

(1)不能调用拷贝构造函数区初始化匿名对象
(2) 对象作为函数的参数 如果实参与形参都是普通对象 那么就会调用拷贝构造
(3)函数返回局部对象,在qt中会被优化,从而调用不了拷贝构造
系统默认会对任何一个类提供三个函数成员函数:
默认构造函数(空) 默认析构函数(空) 默认拷贝构造函数(浅拷贝)
1、如果用户提供了有参构造,将会屏蔽系统的默认构造函数
2、如果用户提供了有参构造,不会屏蔽系统的默认拷贝构造函数
3、如果用户提供了拷贝构造函数,将会屏蔽系统的默认构造函数和默认拷贝构造函数