c++学习001

类和对象---静态成员

        静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

静态成员分为:

       一、静态成员变量

 1.所有对象共享一份数据

  2.在编译阶段分配内存,全局区

3.类内声明,类外初始化

        静态成员变量不属于某个对象上,所有对象都共享同一份数据,因此静态成员变量有两种访问方式:

 ①通过对象进行访问

  ②通过类名进行访问

 静态成员变量同样具有访问权限,注意声明作用域。

#include<iostream>
#include<string>
using namespace std;
class A
{
public:
	//所有对象公用一份数据
	//编译阶段就分配内存
	//类内申明 类外初始化操作
	static int m_a;  //类内声明
private:
	static int m_b;
};
//类外初始化 加上A类的作用域 " A:: "
int A::m_a = 100;
void test()
{
	A a;
	cout << a.m_a << endl;
	
	A b;
	b.m_a = 200;
	
	cout << a.m_a << endl;

}
//访问方式
void test11()
{
	//通过对象进行访问
	A a;
	cout << a.m_a << endl;
	//通过类名进行访问
	cout << A::m_a << endl;

	//cout << A::m_b << endl; 不可访问!

}
int main()
{
	//test();
	test11();
	return 0;
}

       二、静态成员函数

 1.所有对象共享一个函数

 访问方式:

 ①通过对象进行访问

 ②通过类名进行访问

 2.静态成员函数只能访问静态成员变量

①静态成员函数可以访问静态成员变量

②静态成员函数不可以访问非静态成员变量,因为无法区分是哪个对象的成员变量

 静态成员函数同样具有访问权限,注意声明作用域。

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

class B
{
public:
	static int m_b;
	int m_a;
	//静态成员函数
	static void func()
	{
		m_b = 100; //静态成员函数可以访问静态成员变量
		//m_a = 200;//静态成员函数不可以访问非静态成员变量
		cout << "static void func 的调用" << endl;
	}
private:
	void func2()
	{
		cout << "static void func2 的调用" << endl;
	}
};
int B::m_b = 0;
void test()
{
	//通过对象访问
	B a;
	a.func();
	//通过类名访问
	B::func();

	//B::func2() //不可调用 因为属于private访问权限
}
int main()
{
	test();
	return 0;
}

C++对象模型和this指针

一、c++成员变量和成员函数分开存储

        在c++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上,与静态成员变量,静态成员函数,非静态成员变量分开存储。

        空对象占用内存为1  c++编译器会给每个空对象分配一个字节,是为了区分空对象占用内存的位置,每个空对象也应该有一个独一无二的内存地址。

class Person
{

};
void test0201()
{
	Person p;
	cout << "size of p = " << sizeof(p) << endl; //空对象占用内存为1 c++编译器会给每个空对象分配一个字节,是为了区分空对象占用内存的位置
}

        非静态成员变量属于类的对象上

class Person
{
	int m_a;//非静态成员变量

};
void test0202()
{
	Person p;
	cout << "size of p = " << sizeof(p) << endl; // 4字节 说明非静态成员变量属于类内内存空间

}

        静态成员变量不属于类的对象上

class Person
{
	int m_a;//非静态成员变量
	static int m_b;
};
int Person::m_b = 10;
void test0202()
{
	Person p;
	cout << "size of p = " << sizeof(p) << endl; // 4字节 说明静态成员变量不属于类的对象上

}

        非静态成员函数不属于类的对象上

class Person
{
	int m_a;//非静态成员变量
	static int m_b;
	void func(){}//非静态成员函数
};
void test0202()
{
	Person p;
	cout << "size of p = " << sizeof(p) << endl; // 4字节 说明非静态成员函数不属于类的对象上


}

        静态成员函数不属于类的对象上

class Person
{
	int m_a;//非静态成员变量
	static int m_b;
	void func(){}//非静态成员函数
	static void func2(){}//静态成员函数
};
void test0202()
{
	Person p;
	cout << "size of p = " << sizeof(p) << endl; // 4字节 说明静态成员函数不属于类的对象上

}

二、this指针概念

        通过前面的学习我们知道,在c++中成员变量和成员函数是分开存储的,而每一个非静态成员函数只会诞生一个实例,也就是说多个同类型的对象会公用一块代码,那么问题是:这一块代码是如何区分哪个对象调用的自己呢?

        c++提供的特殊对象指针,this指针,解决上述问题,this指针指向被调用的成员函数所属的对象,this指针是隐含在每一个非静态成员函数内的一种指针,this指针不需要定义,直接使用即可。

用处1 解决名称冲突

错误用法

#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
	Person(int age)
	{
		age = age;//同名 会混淆
	}
	int age;
};
void test0301()
{
	Person p(18);
	cout << "年龄为: " << p.age << endl;

	
}
int main()
{
	test0301();
	return 0;
}

this指针用法

class Person
{
public:
	Person(int age)
	{
		//this指针指向的是被调用的成员函数所属的对象
		this->age = age;
	}
	int age;
};

用处2 返回对象本身用*this

#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
	Person(int age)
	{
		//this指针指向的是被调用的成员函数所属的对象
		this->age = age;
	}
	Person& personadd(Person& p)
	{
		this->age += p.age;

		return *this;//*this指针返回对象本身
	}
	int age;
};
void test0301()
{
	Person p(18);
	cout << "年龄为: " << p.age << endl;
	Person p1(10);
	p1.personadd(p).personadd(p).personadd(p).personadd(p);
	cout << "p1的年龄为:" << p1.age << endl;
	
}
int main()
{
	test0301();
	return 0;
}

三、空指针访问成员函数

        c++中空指针也能调用成员函数,但是要注意有没有用到this指针,如果用到this指针,需要加以判断保证代码健壮性。

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

class Person
{
public:
	void showclass()
	{
		cout << "this is Person class" << endl;

	}
	void showPersonAge()

	{
		if (this == NULL)
		{
			return;
		}
		cout << "age = " << m_age << endl;
	}
	int m_age;
};
void test0501()
{
	Person * p = NULL;
	p->showclass(); //可以运行
	p->showPersonAge(); //不可运行 空指针不可访问属性
}
int main()
{
	test0501();
	return 0;

}

四、const修饰成员函数

常函数

        成员函数后加const后我们称这个函数为常函数

        常函数内不可修改成员属性

        成员属性声明时加关键字mutable,在常函数中仍可以修改

常对象

        声明对象前加const称该对象为常对象

        常对象只能调用常函数

#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
	//this 指针的本质是指针常量 指针的指向是不可以修改的
	//在成员函数后加const,修饰的是this指向,让指针指向的值也不可修改
	void showPerson() const
	{
		//this->m_a = 100; 报错
		this->m_b = 100; //不报错
	}
	void func()
	{

	}
	int m_a;
	mutable int m_b;
};
//常对象
void test0601()
{
	const Person p;
	//p.m_a = 100; //报错
	p.m_b = 100;  //未报错
	//常对象只能调用常函数
	p.showPerson(); //未报错
	//p.func(); 报错 预防修改属性
}
int main()
{
	test0601();
	return 0;
}

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值