欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

string 类,构造器,浅拷贝与深拷贝,拷贝链表

程序员文章站 2022-05-13 20:23:28
...

拷贝构造函数:对象的复制(调用拷贝构造函数)
                类名(类名&);
                注:如果用户不显示的定义拷贝构造,编译器会默认添加拷贝构造
                浅  深

对象的生命周期:
            1、分配空间:数据区(动态区,静态区,堆区)
                 动态区:在函数内实例化的(非staic)对象
                        当函数被调用时,才会分配空间调用构造函数
                 静态区:在函数外,或者staic修饰的对象 
                        当程序运行就会分配空间调用构造函数
                        注:如果static修饰的局部静态区变量,当函数被调用时
                            才调用构造函数
                 堆区:两个运算符分配空间与释放空间
                        new 类型(实参)
                        delete 
                    注:malloc只分配数据空间,new分配空间,实例化对象

定义类的方法时:
        1、在类内定义
            class student
            {
            方法:
                void show()
                {
                }
            };
        2、在类外定义:属于该类
            1、先在类内声明
            class student
            {
            方法:
                void show();
            };
            
            void student::show()
            {
            }

初始化列表:当实例化时,对象调用构造函数分配空间和初始化
      方法1:
        student()
        {
            id=0;
            sex='m';
            strcpy(name,"nul");
        }
        方法2:
        student():id(值),sex(‘m’)
        {
            strcpy(name,"nul");
        }    
        方法1与方法2等价

       在类外如何访问非公有成员?
       解决方法:该类提供一个公有的接口

        类成员的作用域:
        1类的成员作用域:只在类内(只能在类内访问,不能在类访问)

        作用域符:
            类名::成员;

        对象指针变量:专门用于存储对象的指针
        定义指针变量:  类型名* 变量名;    (没有实例化)
        成员属性中有一个特殊的指针:this  指向自己

 

      string类的基本用法 : 

#include<iostream>
#include<string.h>
//系统常用类
#include<string>
using namespace std;
//类:某一类实例的模型
class student
{
//方法
//属性
	
};

int main()
{
/*
	char buf[100]="hell world";
	cout<<buf<<endl;

	char buf1[100];
	//buf1=buf; buf1是首地址  (逐个字符赋值)
	strcpy(buf1,buf);
	cout<<buf1<<endl;

	char buf2[100]=",ni hao";
	
	//buf中的内容为:  hell world,ni hao
	//buf=buf+buf2l;
	strcat(buf,buf2);
	cout<<buf<<endl;
*/
/*
	string s="hello world";
	cout<<s<<endl;
	string s1;
//赋值  =
	s1=s;//赋值
	cout<<s1<<endl;
	
	string s2=",ni hao";
// +
	s=s+s2;
	cout<<s<<endl;
*/
/*
	char buf1[]="abc";
	char buf2[]="abd";
	(buf1>buf2)//比较地址大小
*/
/*  //判断运算符
	int a=0;
	a+=1;	//a=a+1

	string s="abc";
	string s1="abd";
	if(s>s1)
	{
		cout<<"s>s1"<<endl;
	}
	else if(s==s1)
		cout<<"s==s1"<<endl;
	else
		cout<<"s<s1"<<endl;
*/
	string s="hllo";
	s+=" world";
	cout<<s<<endl;
	cout<<"第三个字符:"<< s[2]<<endl;
//发送消息
	cout<<s.length()<<endl;
	//替换
	s.replace(4,5,"12345");//从下标为4的字符开始,替换5个字符,替换为内容为12345
	cout<<s<<endl;

	return 0;
}

 

   构造器 :

   构造函数有无参构造函数,和有参构造函数,还有拷贝构造函数。

#include<iostream>
#include<stdlib.h>
using namespace std;

//定义类
class people
{
//方法
public:	
	//构造器
	people()
	{
		cout<<"我被构造啦"<<endl;
	}
	people(int a)
	{
		cout<<a<<"被构造啦"<<endl;
	}		
//属性
	int id;
	char name[10];
};

void fun()
{
//实例化对象:构造器来分配空间与初始化(发此对象发送构造 消息)
	people lm(1);//有参的构造函数

	//静态:在静态区
	static people lq(4); 
}
//静态区:
people zhl(2);//有参的构造函数
int main()
{
	cout<<"main函数开始执行啦"<<endl;
	fun();//动态区:当函数被调用时,才会分配空间(构造函数)

	//定义指针变量:
	//malloc(sizeof(people));//new people(3);//分配空间 
	people* tzw=new people(3);//堆区实例一个对象 
	
	cout<<"main函数结束啦"<<endl;

	delete tzw;
	return 0;
}

 

     拷贝构造 : 

     student::student(student& s)  {}

     这就是拷贝构造函数  

      调用函数: student s3(s1);  ==>student  s3=s1;    函数名和形参匹配   student::student(student&  s) {}

#include<iostream>
using namespace std;

class student
{
//方法
public:
	//构造器:
	student()
	{
		cout<<"无参构造器"<<endl;
	}
	//重载构造器
	student(int i)
	{
		cout<<"student(int)构造函数"<<endl;
		this->id=i;
	}
	//拷贝构造
	student(student& s);
	int getId()
	{
		return id;
	}
//属性
private:
	int id;
};

//拷贝构造
student::student(student& s)
{
	cout<<"我是拷贝构造函数"<<endl;	
//浅拷贝:简单的把s内容给this
	*this=s;
	
}

int main()
{
/*
//实例化对象:
	student s(1);//有参构造函数
	cout<<s.getId()<<endl;
//对象的赋值:	
	student s2;//无以构造
	cout<<s2.getId()<<endl;
	s2=s;//将s的内容赋值给s2
	cout<<s2.getId()<<endl;
//对象的复制:	
	//student s3(s);
	student s3=s;
	cout<<"s3:"<<s3.getId()<<endl;
*/
	student s1(1);//有参的构造student(int)
	student s2;//无参构造
	//对象赋值
	s2=s1;//简单的内容的替换
	cout<<"s2:"<<s2.getId()<<endl;

	student s3(s1);//调用函数:函数名和形参匹配
	cout<<"s3:"<<s3.getId()<<endl;
}

 

   浅拷贝与深拷贝 : 

#include<iostream>
using namespace std;

class student
{
public:
	//默认构造
	student()
	{
		cout<<"student()"<<endl;
		id=new int;//存放的是堆区首地址
	}	
	student(student& s)
	{
		cout<<"student(&)"<<endl;
		//浅拷贝 
		//*this=s;
		//深拷贝:不仅负责空间内容,还需要关心指针指向
		this->id=new int;
		*id=*s.id; 
	}
	//获取
	int getId()
	{
		return *id;
	}
	void setId(int i)
	{
		
		*id=i;
	}
private://属性
	int* id;//只能存放变量的地址
};

int main()
{
	student s;//实例化:调用构造函数(无参)
	s.setId(100);
	cout<<"s:"<<s.getId()<<endl;
	
	student s2(s);//等价studetn s2=s//拷贝构造:
	cout<<"s2:"<<s2.getId()<<endl;
	cout<<"s:"<<s.getId()<<endl;
	
	//修改s2的内容
	s2.setId(1999);
	cout<<"s2:"<<s2.getId()<<endl;
	cout<<"s:"<<s.getId()<<endl;

	return 0;
}

 

   同样是拷贝构造函数 . 

#include<iostream>
using namespace std;

class people
{
public:
	//构造器:
	people(int,int);
	people(people&);//拷贝构造
	//公有接口
	void display();
public:
	int num;//整型变量:存放整型值
	int* id;//指针变量:存放int的变量的地址
};
//构造器
people::people(int n,int i)
{
	num=n;
	//先开辟空间
	this->id=new int(i);	//malloc
}
//拷贝构造
people::people(people& p)
{
	cout<<"拷贝构造"<<endl;
	//*this=p;//将p的内容复制给自己
	this->num=p.num;
	//先给自己的id分配空间
	this->id=new int(*p.id);    //new int(1)  分配一个整型空间,并初始化为1.
}
void people::display()
{
	cout<<"num="<<num<<" id->"<<*id<<endl;
}

int main()
{
//实例化对象:
	people lf(1,2);//构造器
	lf.display();

//拷贝---构造函数(people)  拷贝构造
	people lily(lf);	//拷贝
	lily.display();
	//修改lily的id的值
	*lily.id=7979;
	lily.display();	
	lf.display();

	return 0;
}

    浅拷贝就是 , 当图中的 实例 lily  需要拷贝 实例 lf  的时候 , 但是事先两个实例所指的 id 的地址是公共  , 指向的是同一个地址,如果 实例 lily 拷贝了 实例  lf  那么将会 把公共的 id 地址的内容给修改了, 将会出现 修改 实例 lily 的时候 ,实例 lf 的id内容也会修改.

     深拷贝 就是,在 实例 lily  需要拷贝  实例 lf  的时候,实例 lily 将会先为自己申请一个空间和 实例 lf 一样大小的空间,将拷贝过去,当此时再修改  实例 lily 的时候实例 lf 将不会出现被修改了的情况.   ( new int(*p id)  //new int(1) 分配一个整型空间,并初始化为 1 )    

 

string 类,构造器,浅拷贝与深拷贝,拷贝链表

   拷贝链表 :

#include<iostream>
#include<stdlib.h>
using namespace std;

//定义节点
struct Node
{
	//数据域:
	int data;
	//指向域
	struct Node* next;//指向域
};

class Cstack
{
//方法
public:
	Cstack();//构造函数
	//栈为满
	bool IsFull();
	bool IsEmpty();
	bool push(int);
	bool pop(int&);
	unsigned short stackLength();//栈的元素的长度
	Cstack(Cstack&);
	Node* backTop();
//容量:指向链表的头结点
private:
	void list(Node* ploc);
	Node* top;
	unsigned short ilen;
};

Cstack::Cstack(Cstack& s)
{
	this->top=NULL;
	this->ilen=0;
	list(s.top);
}

Node* Cstack::backTop()
{
	return this->top;
}

void Cstack::list(Node* ploc)
{
	if(NULL==ploc)
		return;
	list(ploc->next);
	push(ploc->data);
	cout<<ploc->data<<" ";
}

Cstack::Cstack()
{
	top=NULL;//指向空链表
	ilen=0;//长度为0
}

bool Cstack::IsFull()
{
	return false;
}

bool Cstack::IsEmpty()
{
	if(NULL==top)
		return true;
	else
		return false;
}

bool Cstack::push(int d)
{
//1.分配节点:(头插法)
	Node* pnew=(Node*)malloc(sizeof(Node));
	if(NULL==pnew)
		return false;
	pnew->data=d;
	
	//个数
	ilen++;
//2.修改指向域
	pnew->next=top;//新节点指向链表头
	top=pnew;
	return true;
}

bool Cstack::pop(int& value)
{
//栈是否为空
	if(IsEmpty())
		return false;
	//先返回值:
	Node* ptemp=top;
	value=top->data;
	
	top=top->next;
	free(ptemp);

	//长度-1
	ilen--;

	return true;
}

unsigned short Cstack::stackLength()
{
	return ilen;
}

int main()
{
	//实例化:请会计
	Cstack s;
	s.push(1);
	s.push(2);
	s.push(3);

	Cstack s2(s);	//将s拷贝给s2  (拷贝构造)

//先出栈s
	int value;
	while(s.pop(value)==true)
		cout<<value<<" ";
	cout<<endl;
//再出栈s2
	while(s2.pop(value)==true)
		cout<<value<<"-";
	cout<<endl;

/*
	s.list(s.backTop);
	int value;
	s.pop(value);	

	Cstack s2(s);
	s2.list(s2.backTop());
*/

/*
	//栈的长度
	cout<<s.stackLength()<<endl;

	Cstack s1(s);

	int value;
	while(s.pop(value))
		cout<<value<<" ";
	cout<<endl;
*/
	return 0;
}

 

相关标签: 原创