c++类
来源:互联网 发布:知达常青藤中学校官网 编辑:程序博客网 时间:2024/06/06 00:24
一、对象和类
1、构造函数
1.1 C++ 提供两种使用构造函数来初始化对象的方式:
1) Class class=Class(p1 , p2,...);
2) Class class(p1,p2,...);
这两种方式是等价的
与new(动态分配内存)一起使用:
Class *p = new Class(p1,p2...);
我们可以通过指针来管理该对象
1.2 默认构造函数
如果一个类没有提供任何构造函数,c++将自动提供默认构造函数,例如
Class class ; //使用的默认构造函数
当我们提供了任何非默认构造函数(例如:Class(p1)),但没有提供默认构造函数,则上面的定义就会出错。
在设计的类的时候,通常应该提供对所有成员变量做隐式初始化的默认构造函数
下面举个例子:
//Class.h#ifndef CLASS_H#define CLASS_H#include <iostream>class Class{ private: int m_a; int m_b; public: Class() { std::cout<<"默认构造函数"<<std::endl; m_a=10; m_b=10; } Class(int,int); ~CLass(){ std::cout<<"bye~ "<<m_a<<std::endl; } void show();};#endif
//Class.cpp#include <iostream>#include "Class.h"void Class::show(){ std::cout<<"m_a:"<<m_a<<" m_b:"<<m_b<<std::endl;}Class::Class(int a,int b){ std::cout<<"构造函数"<<std::endl; m_a=a; m_b=b;}
//main.cpp#include <iostream>#include "Class.h"using namespace std;int main(){ Class a; //print 默认构造函数 a.show(); // m_a:10 m_b:10 a=Class(1,2); //构造函数 a.show(); //m_a:1 m_b:2 Class b(3,4); //隐式形式 b.show(); Class* c=new Class(); //默认构造函数 Class* d=new Class; //默认构造函数 Class e=Class(); //默认构造函数 Class f(); //声明一个函数, }
定义在类声明中的函数,都将自动成为内联函数
2、析构函数
析构函数没有参数
静态存储类对象,在程序结束时候,自动调用;自动存储类型,将在程序执行完该代码块的时候,自动调用;通过 new 创建的,当时候delete的时候调用。
还是用上面的类,改一下main方法,
//main.cpp #include <iostream>#include "Class.h"using namespace std;Class g(1,1);void fun1(){ cout<<"fun1()"<<endl; a.show();}int main(){ cout<<"main()"<<endl; fun1(); Class *p=new Class(30,30); delete p; return 1;}
运行结果:
可以看出,在main函数开始前,就构造了Class g,并且在整个程序结束的时候,自动调用其析构函数
在执行fun1()的时候,构造了Class a,并且在该函数结束的时候,自动调用其析构函数
我们是用new的方法构造了指向一个Class 的指针p, 并手动调用delete 的时候,调用其析构函数
3、this指针
类中中到每个成员函数都(包括构造和析构函数)都有一个 this指针,指向调用对象。
3.1 成员函数后面加const
有 const 修饰的成员函数(指 const 放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员;没有 const 修饰的成员函数,对数据成员则是可读可写的。除此之外,常量(即 const)对象可以调用 const 成员函数,而不能调用非const修饰的函数。
4、类到作用域
4.1 在类中定义常量,使用关键字 static,该常量将于其他静态变量存储在一起,而不是在存储在对象中。
4.2 作用域内枚举
当在相同到作用域中,两个枚举定义中到枚举量会产生冲突:如
enum A { One,Two,Three};
enum B {One,Two,Three};
c++11 提供了一种新的枚举量到作用域为类
enum class A {One ,Two,Three};
enum class B {One,Two,Three};
这样就可以使用下面方法访问
A a = A::One;
B b = B::One;
二、类的使用
2.1 运算符重载
c++允许将运算符重载扩展到用户自定义到类型,例如,允许使用 + 将两个对象相加。编译器将根据操作数和类型决定使用哪种加法定义。
重载运算符到格式L operatorOP (...) 其中OP必须是有效到C++运算符,例如 +,-,*,[]
例子还是上面的Class 类,不过我们新加运算符重载的方法
Class Class::operator+(const Class & t) const{ int a=(*this).get_a()+t.get_a(); int b=(*this).get_b()+t.get_b(); /* Class *res=new Class(a,b); std::cout<<res<<std::endl; return *res; */ Class ret=Class(a,b); return ret; }
main函数:
//main.cpp#include <iostream>#include "Class.h"using namespace std;int main(){ Class *p=new Class(30,30); Class *q=new Class(40,40); Class n=*p+*q; n.show(); cout<<&n<<endl;}
注意:注释掉的代码是为脑洞大开想到,这样到结果是,析构函数只调用了一次,(因为*p *q没有时候delete方法,所以不会调用他们到析构函数),并且operator+函数里面到地址和main里面不一样,为个人估计,这样到用法结果就是内存泄漏,因为operator 中到指向堆到指针在函数结束到时候,就被回收掉了,那么就再也没有指针指向堆中到那个地址
2.2 友元函数
这里暂且先介绍函数《其他还有友元类等)
关键字: friend
可以赋予函数与类到成员函数相同到访问权限。也就是可以访问私有属性
前面重载中我们知道
A=B+2;将被转换成下面到成员函数调用:
A=B.operator+(2);
但是如果是:
A=2+B; 呢?
因为2不是对象,所以编译器不能使用成员函数调用来替换这个表达式,但是我们有另外一种方式:非成员函数,只要我们有一个 operator+(2 , B);就可以了
这样只要在Class 中声明一个友元函数 operator(int ,Class & );
下面结合重载,写一个常用到的例子
2.2.1 重载<<运算符
首先定义Class类
//Class.h#ifndef CLASS_H#define CLASS_H#include <iostream>using namespace std;class Class{ private: int m_num; public: Class(){} Class(int num); int get_num(){return m_num;} friend ostream & operator<<(ostream & os , const Class & c); };#endif
//Class.cpp#include "Class.h"Class::Class(int num){ m_num=num;}ostream & operator<<(ostream & os ,const Class & c){ os<<"num is:"<<c.m_num; return os;}
注意:1.ostream 也是在std命名空间里面
2. 只用传引用就可以了,为了说明不改变 Class中到属性,所以用const
3. 我们返回ostream引用,这样就支持 std::cout<<A<<B;的格式
4.只在类声明原型中才能使用 friend关键字,除非声明的时候同时也定义,否则不能在函数定义中使用friend关键字(编译器会报‘friend’ used outside of class)
我们写一个简单到main函数
#include <iostream>#include "Class.h"using namespace std;int main(){ Class c(10),d(20); cout<<"Class c:"<<c<<" and Class d:"<<d<<endl; //Class c:num is:10 and Class d:num is:20}感觉作用就像java里面重载toString一样,这样就可以自己写一个类的输出打印到信息
- 【c/c++】复数类
- 【c/c++】类模板
- [C/C++] 类
- 【C/C++】嵌套类
- 【C/C++】模板类
- C++------类
- C#--类
- C++-->类
- 【C++】类
- 【C#】类
- c++,C#,java中的类
- c与c++?励志类
- 【C/C++】String类实现
- 【C/C++】类和结构
- 含有指针成员的类的拷贝[C/C++/C#]
- 不能被继承的类[C/C++/C#]
- Objective-C类-Objective-C self 关键字
- [C/C++] 第12章 类 primer
- 磁盘disk 磁道track 磁头head 扇区sector 柱面cylinder 簇cluster
- API 与 ABI 的具体含义
- MFC屏蔽esc键盘消息
- Windows平台下Pin的编译
- 【PHP】进一法取整、四舍五入取整、忽略小数等的取整数方法大全
- c++类
- Android四大组件之ContentProvider使用实例
- 二叉平衡树的实现,AVL平衡树的实现与分析及测试
- Design Pattern--Singleton
- MFC中的类及函数
- ruby截取字符串
- Maven单元测试
- Apache+Tomcat+mod_proxy集群
- Jump Game