c++之类和对象:对象特性

对象的初始化和清理

#include<iostream>
#include<string>
using namespace std;

//构造函数:初始化 
//析构函数:清理 
class Person
{
public:
	//1.构造函数 
	//构造函数没有返回值 不用写void
	//函数名 与类名相同
	//可以有参数 可以发生重载
	//创建对象时,构造函数会自动调用,只调用一次
	Person()
	{
		cout<<"构造函数的调用"<<endl;
	 } 
	//2.析构函数
	// 没有返回值 不用写void
	//函数名 与类名相同 在名称前写~ 
	//不能有参数 不可以发生重载
	//对象销毁前,会自动调用析构函数,只调用一次
	~Person()
	 {
		cout<<"析构函数的调用"<<endl;
	 } 
	
 } ; 
 
int main(){
	Person p; //在栈上的数据  
	
	return 0;
} 

构造函数的分类和调用

#include<iostream>
#include<string>
using namespace std;

//构造函数的分类
//按参数分:有参构造和无参构造
//按类型分:普通构造和拷贝构造 

//三种调用方式:括号法 显示法 隐式转换法 
class Person
{
public:
	//构造函数 :普通 
	Person()//无参构造 默认构造 
	{
		cout<<"构造函数的调用"<<endl;
	 } 
	 Person(int a)//有参构造 
	{
		age=a;
		cout<<"有参构造函数的调用"<<endl;
	 } 
	 //拷贝构造函数
	 Person(const Person &p)
	 {
	 	//将传入的人身上所有的属性 拷贝到我身上 
	 	age=p.age;
	 	cout<<"拷贝构造函数的调用"<<endl;
	  } 
	~Person()
	{
		cout<<"析构函数的调用"<<endl;
	 } 
	 int age;
 
	
 } ; 
 
 void test01()
 {
 	//1、括号法
	 Person p1;//默认构造函数调用 加括号会被认为是函数声明,不会认为实在创建对象 
	 Person p2(10);//有参构造函数调用
	 Person p3(p1); 
	//2、显示法 
	Person p11;
	Person p22=Person(10);//Person(10)是一个匿名对象 匿名对象当前行结束后系统会自动回收 
	Person p33=Person(p2);
	//3、隐式转换法 
	Person p4=10;//相当于写了Person p4=Person(10); 
	Person p5=p4;//Person p5=Person(p4)
  } 
 
int main(){
	test01(); 
	
	return 0;
} 

拷贝构造函数的调用时机

//拷贝构造函数调用时机
//1、使用一个已经创建完毕的对象来初始化一个新对象
//2、值传递的方式给函数参数传值
//3、值方式返回局部对象

构造函数调用规则

只要创建一个类 编译器会提供三个默认函数

1.默认构造函数 (无参,空实现)

2.默认析构函数(无参,空实现)

3.默认拷贝构造函数,对值属性进行拷贝

调用规则如下

1.如果我们定义有参构造函数,编译器不会提供默认构造函数,但提供默认拷贝构造函数

2.如果用户定义了拷贝构造函数,编译器将不会提供其他构造函数

深拷贝与浅拷贝

#include<iostream>
using namespace std;

//深拷贝与浅拷贝 

class Person 
{
public:
	Person()
	{
		cout<<"Person默认构造函数调用"<<endl;
	}
	Person(int age,int height)
	{
		cout<<"Person有参构造函数调用"<<endl;
		m_age=age;
		m_height=new int(height);//new创建堆区的空间 返回了地址 所以用指针接受 
		
	}
	person(const Person &p)
	{
		cout<<"拷贝构造函数调用"<<endl;
		m_age=p.m_age;
		//m_height_=p.m_height;编译器默认实现
		//深拷贝操作
		m_height=new int(*p.m_height);//开辟一个新的空间放变量 
	}
	~Person()
	{
		//将堆区开辟的数据做释放操作 
		if(m_height!=NULL)
		{
			delete m_height;
			m_height=NULL;//防止野指针出现 
			//如果进行浅拷贝 内存会释放两次出错 
		 } 
		cout<<"Person析构函数调用"<<endl;
	 } 
	int m_age;
	int*m_height; 
 } ;
 void test01()
 {
 	Person p1(20,160);
	cout<<"p1的年龄为"<<p1.m_age<<"身高为"<<*p1.m_height<<endl;
	Person p2(p1); //p1初始化p2 
	cout<<"p2的年龄为"<<p2.m_age<<"身高为"<<*p2.m_height<<endl;//编译器的默认拷贝参数进行值传递 
  } 
	int main(){
		test01();
		return 0;
	}

初始化列表

#include<iostream>
using namespace std;

//初始化列表 

class Person 
{
public:
	Person(int a,int b,int c):m_a(a),m_b(b),m_c(c)
	{
		
	}
	int m_a;
	int m_b;
	int m_c;
 } ;
 void test01()
 {
 	Person p(10,20,30);
 	cout<<"m_a="<<p.m_a<<endl;
 	cout<<"m_b="<<p.m_b<<endl;
 	cout<<"m_c="<<p.m_c<<endl;
  } 
	int main(){
		test01();
		return 0;
	}

对象成员

#include<iostream>
#include<string> 
using namespace std;

//类对象作为类成员 
//c++类中的成员可以是另一个类的对象  该成员为对象成员 
class Phone
{
public:
	Phone(string pname)
	{
		m_pname=pname;//手机品牌名称 
	}
	string m_pname;	
};//m_Phone 
class Person 
{
public:
	Person(string name,string pname):m_name(name),m_Phone(pname)
	{
		
	}
	void playgame()
	{
		cout<<m_name<<m_Phone.m_pname<<endl;
	 } 
	//姓名
	string m_name;
	//手机
	Phone m_Phone; //Phone对象在这里作为成员 
 } ;
 //当其他类的对象作为本类成员  构造时先构造类对象 再构造自身 析构相反 
 void test01()
 {
 	Person p("张三","华为");
 	p.playgame();
  } 
	int main(){
		test01();
		return 0;
	}

静态成员变量

#include <iostream>
using namespace std;

class Student{
public:
    Student(char *name, int age, float score);
    void show();
private:
    static int m_total;  //静态成员变量
private:
    char *m_name;
    int m_age;
    float m_score;
};

//初始化静态成员变量
int Student::m_total = 0;

Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){
    m_total++;  //操作静态成员变量
}
void Student::show(){
    cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<"(当前共有"<<m_total<<"名学生)"<<endl;
}

int main(){
    //创建匿名对象
    (new Student("小明", 15, 90)) -> show();
    (new Student("李磊", 16, 80)) -> show();
    (new Student("张华", 16, 99)) -> show();
    (new Student("王康", 14, 60)) -> show();

    return 0;
}

静态成员函数

#include<iostream>
using namespace std;

//静态成员函数 
//所有对象共享一个函数
//静态成员函数只能访问静态成员变量 
class Person 
{
public:
	static void func()
	{
		cout<<"静态函数调用"<<endl;
		m_a=100;
	 } 
	 static int m_a;
	 
 } ;
 int Person::m_a=0;
 void test01()
 {
 	//通过对象访问 
 	Person p;
 	p.func();
 	//通过类名访问
	 Person::func(); 
  } 
	int main(){
		test01();
		return 0;
	}

对象模型

#include<iostream>
using namespace std;

//对象模型
//成员变量和成员函数是分开存储的 
//非静态成员变量 属于类的对象上(只有这个属于类对象上) 
//非静态成员函数 不属于类对象上 
class Person 
{
public:
	
	 
 } ;

 void test01()
 {
 	Person p;
 	//空对象占用内存空间为1 
 	cout<<"size of p:"<<sizeof(p)<<endl; 
  } 
	int main(){
		test01();
		return 0;
	}

this指针

#include<iostream>
using namespace std;

//this指针:指向被调用的成员函数所属的对象
//用途:解决名称冲突 ;返回对象本身用*this 
 
class Person 
{
public:
	Person(int age)
	{
		this->age=age;
	}
	Person& PersonAddage(Person&p)//用引用的方式 
	{
		this->age+=p.age;
		return *this;//*this指向p2的本体 
	 } 
	int age; 
 } ;

 void test01()
 {
 	Person p1(18);
 	
 	cout<<"年龄为"<<p1.age<<endl; 
  } 
   void test02()
 {
 	Person p1(10);
 	Person p2(20);
 	//链式编程思想 
 	p2.PersonAddage(p1).PersonAddage(p1).PersonAddage(p1); 
 	cout<<"p2年龄为"<<p2.age<<endl; 
  } 
	int main(){
		test01();
		test02();
		return 0;
	}

空指针可以调用成员函数

const修饰成员函数

const修饰成员函数:常函数(在后面加const,修饰this指向,让指针指向的值也不能修改)
1、常函数内不可以修改成员属性
2、成员属性声明时加关键字mutable后,就可以修改
常对象:
1、声明前加const
2、只能调用常函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值