编程语言
首页 > 编程语言> > C++之------类和对象

C++之------类和对象

作者:互联网

类的结构

class text{

public: 
	//公有数据成员
	//公有成员函数
protected:
    //保护数据成员
    //保护成员函数
private:
	//私有数据成员
	//私有成员函数
};

普通成员函数

#include <iostream>

using namespace std;
class text{

public:
    void fun(int a,int b);
    void prit();
private:
    int num1;
    int num2;
};
void text::fun(int a,int b)
{
    num1=a;
    num2=b;
}
void text::prit(void)
{
    cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
    text op1;
    op1.fun(1,2);
    op1.prit();
    return 0;
}

运行结果

num1=1 num2=2

注意

1、不能在类里面直接给成员函数赋值
2、类是是一种类型,只有定义了对象后系统才会为对象分配存储空间,以存放对象中的成员。并不是说类不占据内存空间的,要注意一个空类的字节大小为1.
3、在类的内部所有成员之间都可以通过成员函数直接访问,但是类的外部不能访问对象的私有成员。

内联成员函数

内联函数要注意
.
内联函数里面不能含有for、switch、while等,尽可能的简单防止出现错误或者数据沉凹。

隐式声明:

#include <iostream>

using namespace std;
class text{

public:
    void fun(int a,int b)
    {
    num1=a;
    num2=b;
    }
    void prit()
    {
    cout<<"num1="<<num1<<" num2="<<num2<<endl;
    }
private:
    int num1;
    int num2;
};

int main()
{
    text op1;
    op1.fun(1,2);
    op1.prit();
    return 0;
}

显示声明

#include <iostream>

using namespace std;
class text{

public:
   inline void fun(int a,int b);// inline可以省略不写
   inline void prit();
private:
    int num1;
    int num2;
};
inline void text::fun(int a,int b)
{
    num1=a;
    num2=b;
}
inline void text::prit()
{
 cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
    text op1;
    op1.fun(1,2);
    op1.prit();
    return 0;
}

对象可以访问公有成员变量,私有不行。

构造和析构函数

构造函数
构造函数有什么用?

简单点来说就是初始化类里面的成员变量
1、构造函数名称必须和类重名
2、构造函数可带参也可不带参
3、构造函数函数体写在类内部或者外部都可以
4、构造函数不可以有返回值,不可用void

#include <iostream>

using namespace std;
class text{
public:
   text(int a);
   void prit();
private:
    int num1;
    int num2;
};
text::text(int a)
{
    num1=a;
    num2=3;
}

void text::prit()
{
 cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
    text op1(0);//声明对象的时候,自动调用构造函数
    op1.prit();
    return 0;
}

构造函数还可以这样调用

int main()
{
    text * op1=new text(0);
    op1->prit();
    return 0;
}

构造函数定义时候还可以默认带参

text(int a=0);

析构函数

析构函数主要作用时间是类结束时候使用的,自动调用。主要是做一些清理工作
1、析构函数必须和构造函数同名,前面加一个~
2、析构函数不能有返回值(void也不行),不能有参数,而且不能重载,一个类中只能有一个析构函数
3、当撤销对象时,编译系统会自动调用析构函数
4、每个类都必须有一个析构函数,如果没有写,系统会自动生成一个析构函数:
类名::类名()
{ }

#include <iostream>

using namespace std;
class text{
public:
   text(int a);
   ~text();
   void prit();
private:
    int num1;
    int num2;
};
text::text(int a)
{
    cout<<"构造函数使用中"<<endl;
    num1=a;
    num2=3;
}
text::~text()
{

    cout<<"析构函数使用中"<<endl;
}
void text::prit()
{
 cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
    text op1(0);
    op1.prit();
    return 0;
}

运行结果

构造函数使用中
num1=0 num2=3
析构函数使用中

我们改一下main函数

int main()
{
    text *op1=new text(0);
    op1->prit();
    return 0;
}

运行结果

构造函数使用中
num1=0 num2=3

为什么这样的构造函数调用析构没有运行呢?
因为new后没有delete。也就是对象没有结束。所以类没有销毁
改正

int main()
{
    text *op1=new text(0);
    op1->prit();
    delete op1;
    return 0;
}

运行结果

构造函数使用中
num1=0 num2=3
析构函数使用中

拷贝构造函数
自定义拷贝构造函数

#include <iostream>

using namespace std;
class text{
public:
   text(int a);//构造函数
   text(const text &p);//自定义构造函数
   ~text();//析构函数
   void prit();
private:
    int num1;
    int num2;
};
text::text(int a)
{
    cout<<"构造函数使用中"<<endl;
    num1=a;
    num2=3;
}
text::text(const text &p)
{
    num1=p.num1;
    num2=p.num2;
}
text::~text()
{

    cout<<"析构函数使用中"<<endl;
}
void text::prit()
{
 cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
    text op1(0);
    op1.prit();
    text op2(op1);
    op1.prit();
    return 0;
}

这种调用写法也没有问题

int main()
{
    text op1(0);
    op1.prit();
    text op2=op1;
    op1.prit();
    return 0;
}

结果:

构造函数使用中
num1=0 num2=3
num1=0 num2=3
析构函数使用中
析构函数使用中

分析

为什么在最后析构?因为return 0时候才资源回收,内存释放.

默认拷贝构造函数

#include <iostream>

using namespace std;
class text{
public:
   text(int a);//构造函数
   ~text();//析构函数
   void prit();
private:
    int num1;
    int num2;
};
text::text(int a)
{
    cout<<"构造函数使用中"<<endl;
    num1=a;
    num2=3;
}
text::~text()
{

    cout<<"析构函数使用中"<<endl;
}
void text::prit()
{
 cout<<"num1="<<num1<<" num2="<<num2<<endl;
}
int main()
{
    text op1(0);
    op1.prit();
    text op2=op1;
    op1.prit();
    return 0;
}

运行结果

构造函数使用中
num1=0 num2=3
num1=0 num2=3
析构函数使用中
析构函数使用中

深拷贝与浅拷贝
我们写这样一个程序

#include <iostream>
#include <cstring>
using namespace std;
class text{
public:
   text(char * str,int num);//构造函数
   ~text();//析构函数
   void prit();
private:
    char * name;
    int old;
};
text::text(char * str,int num)
{
    cout<<"构造函数使用中"<<endl;
    name= new char[strlen(str)+1];
    strcpy(name,str);
    old=num;
}
text::~text()
{

    cout<<"析构函数使用中"<< name<<endl;
    delete []name;
}
void text::prit()
{
 cout<<"name="<<name<<" old="<<old<<endl;
}
int main()
{
    text op1("哈哈",99);
    op1.prit();
    text op2=op1;
    op2.prit();
    return 0;
}

我在Windows下的codeblocks运行没有问题
在这里插入图片描述
实际上是不能运行的,创建对象op1时候调用了构造函数,创建对象op2的时候:text op2=op1;使用默认的拷贝构造函数,op2并没有调用text::text(char * str,int num)函数。op2使用的内存其实还是op1的。但是析构运行了两次,就是释放了两次,所以说肯定是报错的。我在Linux运行同样的代码

在这里插入图片描述
结果就报错了。
解决方法:

#include <iostream>
#include <cstring>
using namespace std;
class text{
public:
   text(char * str,int num);//构造函数
   text(const text &p);
   ~text();//析构函数
   void prit();
private:
    char * name;
    int old;
};
text::text(char * str,int num)
{
    cout<<"构造函数使用中"<<endl;
    name= new char[strlen(str)+1];
    strcpy(name,str);
    old=num;
}
text::text(const text &p)
{
  cout<<"深拷贝构造"<<endl;
  name=new char[strlen(p.name)];
  old=p.old;


}
text::~text()
{

    cout<<"析构函数使用中"<< name<<endl;
    delete []name;
}
void text::prit()
{
 cout<<"name="<<name<<" old="<<old<<endl;
}
int main()
{
    text op1("哈哈",99);
    op1.prit();
    text op2=op1;
    op2.prit();
    return 0;
}

在这里插入图片描述

标签:op1,对象,text,C++,int,析构,------,prit,构造函数
来源: https://blog.csdn.net/qq_42695024/article/details/115540789