类的成员函数与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)两个类要共享数据的时候