C++面向对象的讲解(一)(简单学习)

C++类的讲解

1、面向对象和类的介绍

1)面向对象
C语言使用面向过程的编程方式,而C++则增加了面向对象的编程方式。

面向过程:分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
面向对象 :把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。 性能对比:

优缺点:
1)面向对象易维护、易复用、易扩展。 因为面向对象有封装、继承、多态性的特性,所以可以设计出低耦合的系统,使系统更加灵活、更加易于维护。但是,面向对象性能比面向过程低。
2)面向过程性能比面向对象高。 因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix 等一般采用面向过程开发。但是,面向过程没有面向对象易维护、易复用、易扩展。

面向对象的三大特性:封装、继承、多态

2)类
类是一种将抽象(问题的本质)转换成用户自定义的类型的一种C++工具,它将数据表示和操纵数据的方法组合成了一个整洁的包。这个包提供对外的接口让用户调用。

类与结构的区别:类是C++对结构进行扩展后的结果。但结构的默认访问类型是public,而类为private。

2、类的建立

1、类的声明
(继承相关的内容在之后会讨论)

#include<iostream>
using namespace std;
class student//自己命名的类名
{
public://公共成员,也是一种公共接口,其内部的函数和数据可以被外部建立的对象直接调用
……
protected://保护成员,内部的函数和数据不可以被外部建立的对象直接调用,但可以被公有继承的类调用
……
private://私有成员,内部的函数和数据不可以被外部建立的对象直接调用
……
}

int main(){
{
student s;//类名 对象
}

关键字public和private和protect是类的控制访问,在类中的顺序没有固定要求,这三个分别描述了对类成员的不同的访问权限。但类中可以互相调用彼此,不受限制。
当没有使用任何的访问控制关键字时,默认算是private!

3、成员函数

1、成员函数的说明
1、类中成员函数有三种定义方式
1)直接在类中定义

class student
{
public:

void function(int a,int b){//在类中直接建立函数,并调用私有成员里的变量
x=a;
y=b;
}

private:
int x,y;
}

2)在类声明中只给出成员函数的原型,成员函数的定义则放在类的外部

class student
{
public:

void function(int,int);//声明函数的返回类型(void),形参类型(int),函数名(function)

private:
int x,y;
}

void student::function(int a,int b)//::表示作用域,student::放在前面表示声明的函数属于student类
{
x=a;
y=b;
}

3)将函数作为内联函数进行处理

class student
{
public:

inline void function(int,int);//inline表示内联函数,声明函数的返回类型(void),形参类型(int),函数名(function)

private:
int x,y;
}

inline void student::function(int a,int b)//inline表示内联函数,::表示作用域,student::放在前面表示声明的函数属于student类
{
x=a;
y=b;
}

2、成员函数的使用
使用成员运算符调用成员函数

class print
{
public:

void _print(){
cout<<"你好!";
}

}

int main(){

print s;
s.print();
return 0;

}

输出:

你好!

4、构造函数和析构函数

构造函数的介绍:
当类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数,其作用是初始化对象的数据成员
构造函数在类中不可缺少且函数名与类相同,构造函数不能有返回类型和返回值。

构造函数可以重载!(即下面几种构造函数可以共存)

构造函数建立在公有成员中,否则外部类对象无法调用构造函数来实现数据成员初始化!!!

构造函数的分类:
1)默认构造函数
如果你创建一个类时没有写任何构造函数,系统会自动生成默认的无参构造函数

class student
{
public:
/*
student(void){//系统自动创建的无参构造函数,但默认值可能不为0
x=0;
y=0;
}
*/
void function(int,int);//声明函数的返回类型(void),形参类型(int),函数名(function)

private:
int x,y;
}

2)初始化构造函数

class student
{
public:

student(int _x,int _y){//可以在类的对象建立的时候初始化对象内的数据的值
x=_x;
y=_y;
}

private:
int x,y;
}

int main(){
student s(5,6);//调用了构造函数,将5和6传递给了s对象里的x和y,使对象s内数据成员被初始化了
return 0;
}

3)复制(拷贝)构造函数
用于对象之间的值传递
默认拷贝构造函数
即没有定义构造函数,此时编译器会给我们自动产生一个拷贝构造函数,其作用是将另一个对象里的所有数据复制到该对象。

class student
{
public:

private:
int x,y;
}

int main(){
student s(5,6);
student c=s;//或者student c(s),作用相同,使用默认拷贝构造函数,将对象s当作参数传入c对象中,把s中所有数据传给对象c
}

自定义拷贝构造函数
可以自己定义要传送的数据

class student
{
public:

student(const student& c){//将对象c的x的值传给该类对象中的x,这里要传递的参数可以自己定义
x=c.x;
}

private:
int x,y;
}

int main(){
student s(5,6);
student c=s;//或者student c(s),作用相同,使用拷贝构造函数,将对象s当作参数传入c对象中,仅仅将s中的5传递给c中的x,没有全部传递(依据定义的拷贝构造函数)
}

4)类型转换构造函数
即实现类对象的数据类型的转换
只有一个参数

class student
{
public:

student(double c){//将对象c的x的数据类型变成double
x=c;
y=0;
}

private:
int x,y;
}

int main(){
student s=5.0;//调用了类型转换构造函数,将s.c的类型变成了double并赋值为5.0,c.y则为0
}

析构函数的介绍——
与构造函数相反,析构函数是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在生命周期结束时,C++编译系统会自动调用析构函数,来完成类的一些资源清理工作。

析构函数的特性——
1)析构函数名是在类名前加上字符~,且无返回类型,无参数,无返回值。
2)一个类有且只有一个析构函数。若用户没有显式定义,系统会自动生成默认的析构函数。
3)析构函数因为没有参数所以不能重载

class student
{
public:

student(int _x,int _y){//可以在类的对象建立的时候初始化对象内的数据的值
x=_x;
y=_y;
}
~student(){}//析构函数
private:
int x,y;
}

5、类的运算符重载

当我们使用string类时,经常会用到 string定义的两个对象直接相加,这是怎么办到的呢?
这就用到了类的运算符重载,即在类中定义一个该对象与其他对象的运算函数,最后返回该对象,实现两个类的运算。
双目运算符形参为另一对象,单目运算符则不必写形参名!

class student
{
public:

student operator +(const student&c){//student为返回类型,const student&c为参数,+为运算符,使用const表示只读,不能改变对象c内的数据
x=x+c.x;//this.x=this.x+c.x
y=y+c.y;//this.y=this.y+c.y
return *this;//返回this指针
}

private:
int x,y;
}

int main(){
student s(5,6);
student c=s;
c=c+s;//c.x=10,c.y=16
//另一种写法:c=operator+(c,s)
}

这里补充关于this指针的知识点:
在C++中,每个对象都能通过this指针来访问自己的地址。this指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。

class student
{
public:
/*student(int _x,int _y){//省略this指针写法
this.x=_x;
this.y=_y;
}*/
student(student *const this,int _x,int _y){//编译器眼中的函数
x=_x;
y=_y;
}

private:
int x,y;
}

关于const与函数的补充:
当const在函数名前面的时候修饰的是函数返回值,在函数名后面则表示是常成员函数,该函数不能修改对象内的任何成员,即只能发生读操纵,不能发生写操作!

6、友元函数

1、为什么要使用友元函数?

类的封装性实现了数据隐藏,即类的私有成员在该类的作用域之外是不可见的。
但有时可能需要在类的外部访问类的私有成员,
为此 C++提供了一种允许类外的函数或其他的类访问该类的私有成员的方法,它通过关键字 friend 把其他类或函数声明为一个类的友元。

2、友元函数的定义与声明

友元函数是声明在类体内的一般函数,也可以是另一个类中的成员函数。友元函数并不是这个类中的函数,但它具有这个类中成员函数所具有的访问该类所有成员的功能。

1)使用普通函数作为友元函数
这样可以使用普通函数(已经定义的友元函数)在外部调用该类的数据成员。
语法:

friend 函数返回值类型 函数名(形式参数列表);

例子:

class student
{
public:
	student(int _age, string _name, string _id) {
		age = _age;
		name = _name;
		id = _id;
	}
	friend void function1(student &a) {//定义友元函数,作用:年龄+1,类型为student,即类名,使用&是为了传递可以改变的参数,作用类似指针
		a.age++;
	}
	friend int function2(student &a,student &b){//定义友元函数,返回两个对象的年龄和
	  return a.age+b.age;
	}
	void print() {
		cout << age << " " << name << " " << id;
	}
	
private:
	int age;
	string name;
	string id;
};

int main() {
	student s1(23,"波哥","2017217293");
	student s2(23,"徽哥","2017217292")
	function1(s1);//23+1
	int s=function2(s1,s2);//24+23
	s.print();
}

从上例可以看出,

  • 友元函数与普通函数的唯一区别就是友元函数需要在类中定义;
  • 友元函数(使用普通函数)的调用不用通过对象和 . 运算符,可以直接在外部调用;
  • 因为友元函数是要从外部访问类对象内部的,所以友元函数的形参里需要出现类对象,以便调用;
  • 因为友元函数是在类中定义的,所以可以调用形参中对象的内部数据

2)类的成员函数作为另一个类的友元函数
类中的成员函数作为另一个类的友元函数,其语法格式如下:

friend 类名::函数返回值类型 函数名(形式参数列表);

例子:

#include <iostream>
using namespace std;
class B; //先声明B类,防止A类中调用function函数出错
class A //定义A类
{
public:
    A(int _x)
    {x=_x;}
    void print()
    {
        cout << x <<endl;
    }
    void function(B &var);//定义A的一个成员函数,准备将其作为B的友元函数,所以形参类型为B类
private:
    int x;
};
class B //定义 B 类
{
public:
    B(int _y)
    {y = _y;}
    void print()
    {
        cout << y << endl;
    }
    friend void A::function(B &var){ //将 A 类中的成员函数 function() 声明为 B 类的友元函数,并定义函数功能
        a = var.b;
    }
private:
    int y;
};

int main()
{
    A m(2);
    B y(3);
    m.func(y); //A类对象m使用成员函数(友元函数)来访问B类成员函数
    m.print();
    return 0;
}

3、注意事项
在使用友元函数时,还需要注意以下几点:

  • 友元函数必须在类的定义中声明;
  • 友元函数的声明可以出现在类的任何地方,包括在 private 和 protected 部分;
  • C++ 不允许将某个类的构造函数、析构函数和虚函数声明为友元函数。
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值