类的成员函数与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)两个类要共享数据的时候
版权声明:本博客所有文章均为原创,欢迎交流,欢迎转载;转载请勿篡改内容,并且注明出处,谢谢!
时间: 2024-10-21 03:05:41