【c++】类与对象(1)

类的定义

类的定义格式

:具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。
定义类的关键字:class
这里定义一个栈类来举例

class Stack//定义一个栈 
{
public:
  void Init(int capacity=4)
  {
    _array=(int*)malloc(sizeof(int)*capacity);
    assert(_array);
    _capacity=capacity;
    _top=0;
  }
private:  
  int*_array;
  size_t _capacity;
  size_t _top;
} 

类名是“Stack”,在“{}”里的是类的主体。在类里面的函数与变量称为类的成员,函数称为成员函数,变量称为成员变量。
在类中定义的函数一般默认是“inline”
成员变量: 一般为了区分成员变量,我们会在成员变量前加一个特殊标识符。

  int*_array;
  size_t _capacity;
  size_t _top;

class(类)与struct的区别:

初学类的朋友,可能会觉得class与struct相似,这里我们简单讲讲两者的区别。

  1. 类中内容称为类的成员,类中的变量称为类的成员变量或者类的属性
  2. 类中可以定义函数,类中的函数称为类的方法或者类的成员函数
  3. 用栈来举例,结构体中放的只是我们需要的数据,方法是单独写的,但是在类中我们把这些都放在了class的主体中了
  4. 类可以直接使用类名,不需要使用typedef来重命名。(类名就是类型)

在c++中,不仅保留了struct原来的功能,还对struct进行了拓展,在c++中也可以用struct来定义类

//用struct来定义一个Person类
 struct Person
{
public:
	void PersonInit(const char*name,int age,int tel)
	{
		strcpy(_name,name);
		_age = age;
		_tel = tel;
	}
	void Print()
	{
		cout << "名字:" << _name << endl;
		cout << "年龄:" << _age << endl;
		cout << "号码:" << _tel << endl;
	}

private:
	char _name[20];
	int _age;
	int _tel;
};

访问定义符

C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接⼝提供给外部的用户使用。
访问限定符:

  • public:被修饰的内容为公共的,在类外能直接访问
  • private:被修饰的内容为私有的,类外不能直接访问
  • protected:被修饰的内容被保护的,类外不能直接访问

关于“private”与“protected”的区别,需要到继承的内容中才能体现出来,这里不多阐述。

关于访问权限的作用域 :从访问限定符本身开始,到下一个访问限定符为止。

public:
  void Init(int capacity=4)
  {
    _array=(int*)malloc(sizeof(int)*capacity);
    assert(_array);
    _capacity=capacity;
    _top=0;
  }
private:  
  int*_array;
  size_t _capacity;
  size_t _top;

比如在这段代码中,public的作用域就是从自身开始到private上面的“}”结束,priveta的作用域就是从自身开始,知道最后。

一般成员变量是private,成员函数是public,因为成员变量中保存着我们所需要的数据,为了不让数据能被轻易的破坏,就设置private来进行保护。

若class中没有给出访问限定符,默认为private,struct中若没给出访问限定符,默认为public
但在类里面,不管成员是私有的还是公有的,都能直接访问。

类域

的作用是影响编译器的查找,做到名字的隔离
如果不指定类域,编译器在编译时将不会访问类域

Stack.h头文件
#pragma once
#include<iostream>
#include<assert.h>
class Stack
{
public:
	void Init(int capacity = 4);
	
private:
	int* _array;
	int _capacity;
	int _top;
};
Stcak.cpp文件
#include"Stack.h"

void Stack::Init(int capacity)//如果这里没有stack::编译器将会报错。因为没有指定类域,所以编译器在编译时不会到Stack中查找,那么Stack中的成员变量对于编译器来说就是不存在的,所以对于三个不存在的变量进行赋值,这是不被允许的。
{
	_array = (int*)malloc(sizeof(int)*capacity);
	assert(_array);
	_capacity = capacity;
	_top = 0;
}

类的实例化

  1. 用类类型在物理内存中创建一个对象的过程,称为类实例化出对象。
  2. 类就好比一张房屋设计图纸,告诉了人们这个房是怎么样的,几间房,房多大。类就是告诉程序员实例化出的对象有哪些成员变量。
  3. 一个类可以实例化出多个对象,类与对象的关系是一对多1->N。
class Data
{
 private://这是声明
  int _year;
  int _month;
  int _day;
};

int main()
{
  //这是类定义一个对象,也叫类实例化出对象
  Data d1;
  Data d2;
}
//类与对象的关系:1对多,一个类可以实例化出多个对象。

对象大小

类实例化出每个对象,都会在创建一个独立的数据空间,在对象中肯定存储了成员变量,那成员函数是否会被保存对象存储?答案是不会的。
首先,函数被编译时会被编译成一段指令,对象中无法存储,另外这些会被存储在一个独立空间(代码段),那么,对象若想要存储成员函数就只能存储它的指针,但是存储它的指针这有必要吗? 没必要

class Data
{
public:
	void Init(int year,int month,int day)
	{
		_year=year;
		_month=month;
		_day=day;
	}
	void Print()
	{
		cout<<_year<<'/'<<_month<<'/'<<_day<<endl;
	}
 private://这是声明
  int _year;
  int _month;
  int _day;
};

int main()
{
  //这是类定义一个对象,也叫类实例化出对象
  Data d1;
  Data d2;
  d1.Init(1,1,1);
  d2.Init(2,2,2);
  d1.Print();
  d2.Print();
}
//类与对象的关系:1对多,一个类可以实例化出多个对象。

用这段代码举例,定义两个对象d1与d2,在初始化时,不同之处就是传入的初始值不同,调用的是同一个函数,那么我们还有必要每创建一个对象就把成员函数保存到对象中吗?完全没必要,如果保存了,还会造成没必要的空间浪费。

调用函数被编译成汇编指令[call 地址],其实在编译链接时就要找到函数指针,而不是在运行时查找。

成员函数被放到一个公共区域,成员变量被保存到对象中去。
在这里插入图片描述

内存对齐

计算对象大小时,也存在内存对齐规则,与结构体一样:

  1. 第⼀个成员在与结构体偏移量为0的地址处。

  2. 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。

  3. 注意:对⻬数 = 编译器默认的⼀个对⻬数 与 该成员⼤⼩的较⼩值。

  4. VS中默认的对⻬数为8

  5. 结构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。

  6. 如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤⼩ 就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍。

先来一段代码举例:

class A
{
public:
    void Print()
  {
    cout << _ch << endl;
  }
private:
    char _ch;
    int _i;
};
计算A实例化对象的大小

A中,存在两个成员变量 _ch 与_i

_ch是char类型,又是第一个元素,那么它放在偏移量为0的地址出,占1字节

在这里插入图片描述
再来两段代码:

class B
{
public:
  void Print()
  {
    //...
  }
};
************************
class C
{};

类B与C中没有成员变量,那么它的大小是多少字节?答案是1字节。
为什么没有成员变量,还要占1字节?原因很简单:这1字节就是用来占位的,表示对象存在过。

this指针

c++中提供了一个this指针,同来区分函数是被d1调用还是被d2调用。
在编译器编译后,会在函数实参与形参的第一个位置隐示生成一个this指针。
类的成员函数中访问类的成员变量的本质就是通过this来访问。
c++中规定,this指针不能在实参与形参中显示的写入,但能在成员函数中显示的使用

class Data
{
public:
//void Init(Data *const this,int year,int month,int day)
	void Init(int year,int month,int day)
	{
		_year=year;
		_month=month;
		_day=day;
	}
	//void Print(Data *const this)
	void Print()
	{
	//cout<<this->_year<<'/'<<this->_month<<'/'<<this->_day<<endl;
		cout<<_year<<'/'<<_month<<'/'<<_day<<endl;
	}
 private:
  int _year;
  int _month;
  int _day;
};

int main()
{
  //这是类定义一个对象,也叫类实例化出对象
  Data d1;
  Data d2;
  /*
  d1.Init(&d1,1,1,1);
  d2.Init(&d2,2,2,2);
  */
  d1.Init(1,1,1);
  d2.Init(2,2,2);
  /*
  d1.Print(&d1);
  d2.Print(&d2);
  */
  d1.Print();
  d2.Print();
}
//类与对象的关系:1对多,一个类可以实例化出多个对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值