【C/C++学院】0819-/类的成员函数与const-mutable /构造与析构/拷贝构造deletedefault以及深浅拷贝/静态成员函数成员变量类在内存的存储默认参数/友元类以及友元函数-阿里云开发者社区

开发者社区> 开发与运维> 正文

【C/C++学院】0819-/类的成员函数与const-mutable /构造与析构/拷贝构造deletedefault以及深浅拷贝/静态成员函数成员变量类在内存的存储默认参数/友元类以及友元函数

简介: <p><span style="font-family:宋体; font-size:16pt">类</span><span style="font-family:宋体; font-size:16pt">的成员函数与<span style="font-family:Cambria">const</span></span><span style="font-family:宋体; font-si

的成员函数与const-mutable 

成员函数

Fushu.h

#pragma once
#include <iostream>
class fushu
{
public:
	int x;
	int y;
public:
	fushu();
	~fushu();
	void show();
	inline void  showall(int x, int y);//显式内联
	void   setxy(int x, int y);//编译器优化,默认隐式内联
	void show(int x, int y);
	/*
	inline void  showall(int x,int y)
	{
		//复合代码
		std::cout << (this->x = x) << (this->y = y) << std::endl;
	}
	*/
};
//内联函数原则上放在头文件,去掉inline标识符
//内联函数需要展开,(VS2013是要求放在头文件的)
void fushu::showall(int x, int y)
{
	std::cout << (this->x = x) << (this->y = y) << std::endl;
}

Fushu.cpp

#include "fushu.h"

//::前面必须是类或者命名空间

fushu::fushu()
{
	std::cout << "对象被创建" << std::endl;
}

fushu::~fushu()
{
	std::cout << "对象被销毁" << std::endl;
}
//类调用成员函数,需要明确那个类的对象调用
void fushu::show()
{
	std::cout << "show" << std::endl;
}
void   fushu::setxy(int x, int y)//编译器优化,默认隐式内联
{
	this->x = x;
	this->y = y;
	std::cout << (this->x) << (this->y) << std::endl;
}
void  fushu::show(int x, int y)
{
	std::cout << (this->x) << (this->y) << std::endl;
}

成员函数.cpp

#include <iostream>
#include "fushu.h"

void stackrun()
{
	fushu fushu1;//对象在栈上
	fushu1.show();
}

void heaprun()
{
	fushu *pfushu = new fushu;//对象在堆上
	pfushu->show();
	pfushu->showall(10, 9);
	pfushu->setxy(19, 29);
	pfushu->show(1, 2);
	//内部成员函数重载,函数指针,明确了参数,
	delete pfushu;
}

void main()
{
	heaprun();

	std::cin.get();
}

Const-mutable

Constmutalbe.h

#pragma once
#include <iostream>
class constmutable
{
public:
	int a;
	int b;
	int c;
	const int d=0;//常量是必须存在初始化
	mutable int e;//限定了不被const所限制
public:
	void setabc(int a, int b, int c)
	{
		this->a = a;
		this->b = b;
		this->c = c;
	}
	void showabc() const
	{
		//函数const,可以限定不对成员变量赋值,this->a = 10;
		//this->c = 90;
		std::cout << this->a << this->b << this->c << std::endl;
	}
	constmutable();
	~constmutable();
};

Constmutable.cpp

#include "constmutable.h"

constmutable::constmutable()
{
}

constmutable::~constmutable()
{
}

构造与析构

构造函数与赋值的区别

#include<iostream>

//所有的类默认都有一个构造函数,析构函数
//构造函数,重载,
//没有返回值,
class myclass
{
public:
	int num;
public:
	myclass()// :num(4)初始化第一种方式
	{
		//num = 10;第二种方式
		std::cout << "class create";
	}
	myclass(int data) //构造函数可以重载
	{
		std::cout << "class create  by data";
		num = data;
	}
	~myclass()
	{
		std::cout << "class delete";
	}
};

void run()
{
	//myclass myclass1(10);
	//myclass myclass1 = 101;
	//myclass *p = new myclass(102);
	myclass *p (new myclass(102));
	//p(new myclass(105));
	std::cout << (*p).num << std::endl;
	//std::cout << myclass1.num << std::endl;
}


void main1()
{
	run();

	int num = 4;
	num = 4;
	int data(4);
	//data(5);

	std::cin.get();
}

构造与析构的顺序

#include<iostream>

//系统自动给你生成了构造函数与析构函数
//被包含的,最先分配,最后释放
//包含别人的,最后分配,最先释放
class fushu
{
public:
	fushu();
	~fushu();
};

fushu::fushu()
{
	std::cout << "fushu构建" << std::endl;
}

fushu::~fushu()
{
	std::cout << "fushu销毁" << std::endl;
}

class math
{
public:
	fushu fushu1;
	math()
	{
		std::cout << "math构建" << std::endl;
	}
	~math()
	{
		std::cout << "math销毁" << std::endl;
	}
};

void go()
{
	math math1;
}

void main2()
{
	//fushu fushu1;
	go();

	std::cin.get();
}

Explicit

#include <iostream>
#include <array>

class  classobj
{
public:
	int num;
public:
	explicit  classobj(int data)
	{
		this->num = data;
		std::cout << "被构造" << num << std::endl;
	}
	//classobj()
	//{
	//	std::cout << "被构造yuan" << num << std::endl;
	//}
	~classobj()
	{
		std::cout << "被销毁" << num << std::endl;
	}
protected:
private:
};

void main()
{
	//C 语言风格的数组,构造一个数组,销毁一个数组

	classobj obj(0);//单独独有构造函数
	classobj objx[3] = { classobj(0), classobj(1), classobj(2) };//C语言风格数组构造方式
	classobj(*ppobjA)[3] = &objx; //指向数组的指针
	classobj  *pobj ( new classobj(0)) ;

	classobj * ppobj[3];//数组,每一个元素都是指针
	ppobj[0] = new classobj(0);
	ppobj[1] = new classobj(1);
	ppobj[2] = new classobj(2);	

	//classobj *p= new  classobj[10];
///	delete[]p;

	std::cin.get();

}

void main11111()
{
//	classobj  num = 5;//赋值号,类型转换
	//classobj  data(5);

	// classobj  obj;
	classobj obj(0);//创建对象必须合适的构造函数
	//classobj *p= new classobj;

	//C++ 风格数组的作用
	classobj * p = new classobj(5);
	std::array <classobj, 2 > myarray = { obj, *p };

	std::cin.get();
}

拷贝构造deletedefault以及深浅拷贝

拷贝构造

#include<iostream>

//如果声明已经定义,便不会生成
class classA
{
private:
	int a;
	int b;
public:	
	//拷贝构造的规则
	classA(int x, int y)//:a(x), b(y)
	{
		//a = x;
		//b = y;
	}
	void print()
	{
		std::cout <<a << b << std::endl;
	}
};

void main12313()
{
	classA  class1(10,100);//编译器会默认生成默认的构造函数
	classA  class2(class1);//编译器会生成默认的拷贝构造函数
	class1.print();
	class2.print();//默认的拷贝构造函数
	//classA class3(4);

	std::cin.get();
}

Delete-default

//delete可以禁用默认生成的函数,禁用构造可以无法实例化
//禁用拷贝构造,可以实现禁止别人拷贝你
//default默认存在
class myclassA
{
public:
	//myclassA() = delete;//默认删除构造函数,无法实例化
	//myclassA() = default;//默认存在
	//myclassA(const 	myclassA &) = delete;//拷贝构造函数
	//myclassA(const 	myclassA &) = default;
	//=//缺省的赋值函数
	~myclassA();
};

void main211()
{
	//myclassA myclassa1;
	//myclassA myclassa2(myclassa1);
	//myclassA myclassa3 = myclassa1;//重载了=,根据类型进行判断 
	//	myclassA a1;

}

深拷贝浅拷贝

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<string>

class string
{
public:
	char *p;
	int length;
	string(int num,char *str)
	{
		//获取长度,分配内存,拷贝内容
		length = num;
	    p = new char [length];
		memset(p, 0, length);//
		strcpy(p, str);
	}
	string(const string & string1)
	{
		//qian
		//this->p = string1.p;
		//	this->length = string1.length;
		//shen
		this->p = new char[string1.length];
		this->length = string1.length;
		memset(this->p, 0, this->length);//
		strcpy(this->p, string1.p);
	}
	~string()
	{
		delete[] p;//
	}
};

void main()
{
	string *pstr1 = new string(10, "hello");
	std::cout <<pstr1->p<< std::endl;
	string *pstr2 = new string(*pstr1);
	delete pstr1;
	std::cout << pstr2->p << std::endl;

	std::cin.get();
}

void main1()
{
	string str1(10, "hello");
	std::cout << str1.p << std::endl;

	string str2(str1);
	std::cout << str2.p << std::endl;

	std::cin.get();
}

静态成员函数成员变量类在内存的存储默认参数

Class与内存

#include<iostream>

class myclass
{
public:
	int num;
	int data;
	int *p;
	const int coint;
	int & myint;
	static int shu;//声明
	static const int dashu;
public:
	static void go()
	{
	}
	void run()
	{
	}
//常量,引用,必须重载构造函数初始化,
	myclass(int a, int b) :myint(a), coint(b)
	{	//引用就是共用地址,常量新开辟备份机制
		std::cout << &a << "  " << &b << std::endl;
		std::cout << &myint << "  " << &coint << std::endl;
		
		const int *p = &coint;//地址
		std::cout << *p << "   " << coint << std::endl;
		int *px = const_cast<int *>(p);//去掉const转换
		*px = 12;
		std::cout << coint << "  " << *px << std::endl;
	}
	~myclass()
	{
	}
};

int myclass::shu = 0;//初始化
const int myclass::dashu = 20;//常量

void  main()//尝试去掉const属性
{
	const int *px = &(myclass::dashu);
	std::cout << px << std::endl;
	int *p = const_cast<int *> (px);
	*p = 123;//静态常量区可以访问,不可以修改,
	std::cout << *px << "  " << *p << "   " << myclass::dashu;

	std::cin.get();
}

class mywindowW
{
public:
	int  #//引用,必须在构造的初始化,
	//引用今天可以引用这个人,明天引用那个人
public:
	mywindowW(int data) :num(data)
	{

	}
};

int mainrr()
{
	int data = 20;//引用必须初始化,反复赋值,类中的引用必须在构造函数初始化
	mywindowW  my1(data);
	std::cout << my1.num; //加上endl关闭输出,当作地址,否则当作变量
	int dataA = 201;
	my1.num = dataA;
	std::cout << my1.num;//加上endl关闭输出,当作地址,否则当作变量
	std::cin.get();

	return 0;
}

int mainr()
{
	int data2 = 11;

	int  data1 = 22;//引用必须初始化,反复赋值,
	int & da = data1;
	std::cout << da<< std::endl;
	da = data2;
	std::cout << da<<std::endl;

	std::cin.get();
	return 0;
}

class mywindowWW
{
public:
	const int num;
public:
	mywindowWW(int data) :num(data)
	{

	}
};

void mainconst()
{
	int int1 = 20;
	mywindowWW  mywindowWW1(int1);//初始化,常量必须构造的时候初始化
	//类的外部一旦初始化以后,不会读内存,从代码区的符号表自动生成,
	std::cout << mywindowWW1.num << std::endl;

	//mywindowWW1.num = 19;//mywindowWW1”: 不能给常量赋值

	std::cin.get();
}

void main2312312()
{
	//类中的普通成员变量
	//类名 变量名  //栈上
	//类名 *指针名 =new  类名   //堆上
	//类的静态成员  静态区
	//成员函数,静态函数都在代码区,类的函数都是共享
	//myclass myclass1(10, 9);
	//int a(5);
	
	//void(myclass::*p1)() = &myclass::run;
	//代码共享,所有的类对象共享对象,
	//void(*p2)() = &myclass::go;//静态函数,与对象没有关系


	//引用本质就是变量的别名,4个字节,本质是一个指针

	myclass myclass1(10, 9);

	//static const int dashu; 静态区,修改
   //

	//int a;
	//int &ra;
	
	std::cin.get();
}

默认参数

#include<iostream>

class goodclass
{
public:
	int num=1;//默认初始化的值,C++11特定
	const int data=90;//const,少写构造函数
public:
	static void show(goodclass good1)
	{
		std::cout << good1.num << "  " << good1.data<<std::endl;
	}
};

//类中的const默认还是可以修改,与C语言const一致
void main()
{
	goodclass good1;
	goodclass::show(good1);

	const int *px = &(good1.data);
	std::cout << px << std::endl;
	int *p = const_cast<int *> (px);
	*p = 123;
	std::cout << *px << "  " << *p << "   " << good1.data<<std::endl;
	goodclass::show(good1);

	std::cin.get();
}

友元类以及友元函数

1、为什么要引入友元函数???

在实现类之间数据共享时,减少系统开销,提高效率。具体来说:为了使其他类的成员函数直接访问该类的私有变量。 即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。

优点:能够提高效率,表达简单、清晰

缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。

2、什么时候使用友元函数??

      1)运算符重载的某些场合需要使用友元。

      2)两个类要共享数据的时候

















版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章