C++学习笔记day2


前言

本文主要总结了C++中基础的构造函数、拷贝构造函数、析构函数、关键字const、static以及重载分别进行了讨论,对不同函数的特点、作用、调用时机及注意事项,例如:C++默认存在的5种函数、5种不可重载的运算符,设计模式之一的单例模式进行了总结归纳,强化基础知识掌握能力!!


提示:以下是本篇文章正文内容,下面案例可供参考

一、构造函数

1.1 规则、特点(有参、无参)

定义:构造函数是一种创建对象时自动调用的函数,是c++中特殊成员函数
作用:创建对象时初始化对象,为对象的成员变量赋值,仅初始化一次且可根据条件进行初始化

规则和特点:
1.名字必须与类同名 无返回值 可能有参数
2.访问权限一般是public,一旦私有构造函数,那么在类的外部将不能创建对象。
3.不能手动调用 只有在类对象创建时 自动调用		
4.实例化(创建)对象时,只用到一个构造函数

无参构造函数:
#include <iostream>
using namespace std;

class Person
{
	string name;
public:
	//构造函数 格式:1.函数名和类名相同 2.没有返回值 3.参数可有可无
	Person() //无参构造函数
	{
		cout<<"构造函数"<<endl;
		name = "haha";
	}
	Person(string n)
    {
		cout<<"有参构造"<<endl;
		name = n;
	}
	Person(string n,int a){
		name = n;
		age = a;
		cout<<"两个参数的构造函数"<<endl;
	}
public:
	void init(string n){ name = n; }

	void show() {  cout<< name <<endl;  }
};
//2.构造函数的调用时机:创建一个对象时,就会调用构造函数 自动调用
//3.作用:初始化对象中的成员变量的值
//4.构造函数的权限一般为公有,如果私有了,类外无法创建对象了
int main()
{
	Person p;//创建对象时,自动被调用的函数
//	p.Person();//不可以,构造函数不可以手动调用
	p.show();
    Person p1(5);//根据参数调用相应的构造函数
	return 0;
}

1.2 默认构造、类外实现

默认构造函数即: 显示(手动编写构造函数)
1、默认构造函数,当没有显式的定义构造函数时,系统会自动生成一个默认构造函数。
2、默认的构造函数:没有参数也没有逻辑;仅仅为了有构造函数而存在。
3、一旦显式的定义了构造函数,将不会生成默认构造函数

例如:
#include <iostream>
using namespace std;
class Person
{
private:
	int age;
public:
(1)如果这里不显示的定义构造函数,会有一个默认构造函数,没有参数没有逻辑
	所以创建对象的时候不能有参数

(2)因为在这里显示的定义了一个构造函数,所以现在整个类中只有一个构造函数,
所以创建对象的时候必须给实参列表
	Person(int a)  
	{
		age = a;
	}
};
int main()
{
	Person p(1);
	return 0;
}

1.默认的构造函数: 类中没有显示的定义构造函数
2.默认构造函数格式:没有参数 没有逻辑 只是为了存在而存在	
3.只要我们定义了构造函数,默认的构造函数就不存在了

构造函数的类外实现:即声明在类的内部,但函数实现在类外先,格式:类名::构造函数名
例如:
#include <iostream>
using namespace std;

class Person
{
	int age;
public:
	Person();
	Person(int a);
	
};

Person::Person()
{
	cout<<"create..."<<endl;
}
Person::Person(int a)
{
	cout<<"one .."<<endl;
	age = a;
}

int main(int argc, const char *argv[])
{
	Person p;
	Person p1(12);
	return 0;
}		

1.3 初始化列表、this指针

构造函数的初始化列表:冒号形式引出初始化列表  格式:成员变量名(初始值)
注意事项:
1.初始化成员列表的顺序应该和成员声明的顺序保持一致,不建议使用成员初始化其他成员;
2.成员的初始化顺序,是按照声明的顺序进行,和初始化列表的顺序没有关系。
例如:
class Rect
{
private:
	int width;
	int height;
public:
	Rect(int w, int h):width(w),height(h){}
                       //1.初始化列表,用w初始化成员width,用h初始化成员height,
                       //2.初始化列表只能初始化成员变量  ()可以是构造函数的参数,也可是常量
	int perimeter()
	{
		return width*2+height*2;
	}
};

初始化列表分文件实现:实际编写代码中,代码量较大,为了方便阅读、修改、调试,会将函数的声明、实现、调用分文件写,即头文件中放需要添加的头文件、类的声明、函数的声明;函数的具体功能实现写在.cpp中 函数调用在main 中调用

this指针作用:类的每个成员函数中都有一个指针叫this,指向调用成员函数的那个对象。
1.是一个指针,指向当前正在调用成员函数的对象
2.this只能在类的内部使用,在类的内部调用成员都是使用this调用的,可以省略
3.存在的意义是在类的内部,将当前对象当做参数进行传递
例如:
class Person
{
private:
	int age;
public:
	Person(int age)
	{
		this->age = age;//this->age 是指向当前构造函数的对象的age
	}
	void show()
	{
		cout<<this->age<<endl;//就算这里不写this,系统也会给我们补上this,在成员函数中调用成员都是通过this指针调用的。不写this属于隐式调用this
	}
};
int main()
{
	 Person p(1);//创建对象p,所以这里执行构造函数时,构造函数的this指向p
	 p.show();//show中this指向p,所以p调用show
}

二、拷贝构造函数

声明:函数名(类名)(const 类名 &对象名)  	Person(const Person& other)
拷贝构造函数的参数列表必须是 const 类名 &对象名

2.1 默认拷贝构造

默认拷贝构造函数:
1、在没有显式的定义拷贝构造函数时,系统会自动生成一个拷贝构造函数,功能:将成员变量逐个赋值 
2、如果显式的定义拷贝构造函数,并且运行时执行了拷贝构造函数,那么默认拷贝构造函数和默认构造函数都不会被调用了
3、创建一个对象的时候,只会调用一个构造函数(默认拷贝构造也是构造函数)

注意:
默认的构造:没有显示定义构造函数都没有
默认的拷贝构造:没有拷贝构造存在

写了拷贝构造的时候,默认的构造函数还在不?  不再了,因为拷贝构造也是构造函数,只要类中有构造函数,那么默认的构造函数就不在了。

总结:
1. 如果没有自定义的拷贝构造函数则系统自动生成一个默认的拷贝构造函数

Empty(const Empty& o)
{
this->age = o.age;
}

2. 当采用直接初始化或复制初始化实例化对象时,系统自动调用拷贝构造函数
Person p;
Person p2 = p;
Perosn p3(p);

3. 系统默认拷贝构造函数的功能:逐个对成员变量进行赋值

4. 显示的定义了拷贝构造函数,系统默认的就不存在了,
   函数的功能(对变量进行的赋值),就由我们自己来完成了

2.2 3种调用情况、私有化(构造函数、拷贝构造函数)

拷贝构造函数调用三种情况:
第一种:程序中需要创建一个新对象 并用另一个同类的对象对它初始化 
int main()
{
	Person* p = new Person(12);//构造函数
	Person * p1 = new Person(*p);//调用拷贝构造
	p1->show();//12
	
	Person a(2);//构造函数
	Person b = a;//调用拷贝构造
	b.show();//2
	Person c(a);//调用拷贝构造
}

第二种:当函数的参数为类的对象时
*******示例1*******************
void farsight(Person p) //Person p= a;
{
}
int main()
{
	Person a(19);
	//使用对象a初始化函数的参数p,a和p是两个独立的对象
	farsight(a);//会调用拷贝构造
}
第三种:函数的返回值为类对象
如果对象生命周期大于函数,会创建一个新的对象,促发拷贝;
如果函数结束对象就被删除,不会创建新的临时对象,不会促发拷贝

//1.返回的是栈空间对象:没有拷贝,等价于编译器做了优化,栈-->栈 使用同一个 换了一个名字
//2.返回的是堆空间对象:调用拷贝, 把堆空间的对象,复制一份到 栈空间
Person fun2()
{
   // Person p;//栈空间 无参构造  //1
   // cout<<&p<<endl;
   // return p;
    Person* p = new Person;     //2
    cout<<p<<endl;
    return *p;
}

int main()
{

    Person tmp = fun2();
    cout<<&tmp<<endl;
    return 0;
}

总结:
1、无论直接创建对象、作为参数还是返回值,如果两个对象是不同的,只是类型相同就会调用拷贝构造
2、如果是匿名对象给有名对象赋值,那么就不会调用拷贝构造,只是给匿名对象换成了有名的

私有构造函数 不能在类的外部创建对象
私有拷贝构造函数  不能在类的外部复制对象

2.3 深拷贝、浅拷贝

浅拷贝:拷贝指向对象的地址,本质是地址的复制,两个指针指向同一个对象
深拷贝:拷贝指向的对象,本质是对象的复制,两个指针指向不同的对象

注意事项:
浅拷贝容易出现的问题:如果前面的指针将指向的对象释放掉了,那么后面的指针都不可使用且会报错
系统默认是浅拷贝

三、析构函数

3.1 特点、作用、调用时机

析构函数是一个特殊的成员函数 作用与构造函数相反
功能:对象所在的函数已经调用完毕,系统自动调用析构函数去释放空间,避免内存泄漏
声明:没有返回值 名字必须与类名同名 没有参数 名字前 ~
~Person()
{		
	cout<<"析构"<<endl;
}
**注意:1.析构函数不能有参数,所以不能被重载 2.一个类中有且仅有一个析构函数

在栈空间创建的对象,在消亡时会自动调用析构回收资源,而堆空间创建的(new)的对象,必须手动释放(delete),避免造成内存泄漏

3.2 默认析构函数

默认的析构函数:没有参数,没有逻辑 为存在而存在
~Person()
{
	
}

但我们可在默认的析构函数里添加功能,释放堆空间对象数组

四、类、对象

4.1 类对象初始化顺序

类成员的初始化顺序:先成员,后构造
初始化顺序:先按照成员变量的声明顺序初始化成员变量,最后调用构造函数

匿名对象
作用:1、赋值  2、初始化  3、传参数
语法:类型(构造函数的参数列表)
注意:匿名对象的生命周期非常的短(临时的值)  匿名对象不是一个必要的语法,它能让我们的代码变的更加简洁。

示例1:给形参赋值
int main()
{
//创建匿名对象作为函数的参数,省去了额外创建一个对象的步骤,代码简洁了!
    	fun(Person(18, 100));	
	//这是不使用匿名对象的情况
	Person p(18, 100);
	fun(p);
	return 0;
}
示例2::初始化数组
 Person ps[5] = {Person(1), Person(2), Person(3), Person(4), Person(5)};
 for(int i = 0;i < 5;i++)
 {
      ps[i].show();
 }

4.2 const(常函数、常对象)与mutable

常函数特点:
1.常函数中的this是被const修饰的,在常函数中成员变量不能被修改;
2.常函数只能调用常函数;
class Person
{
	int age;
public:
	Person(){}
	Person(int a):age(a){}

	//常函数:1.不可以改变成员变量的值   2.常函数只能调用常函数
	void show() const 
	{
		//++age;错误,值不可以修改
		cout<<age<<endl;
		setAge(25);
	}
	void setAge(int a) const
	{
		//age = a;错误,值不可以修改
		cout<<age<<endl;
	}
};

常对象 
定义:1、const 类名 对象名(实参)  2、类名 const 对象名(实参)
1、成员变量必须有初值 
2、只能调用常成员函数 		
功能:希望对象所有成员的值不被修改

注意事项:
1.自由的对象首选调用自由的函数,没有自由的函数,可以调用常函数
2.常对象:只能调用常函数,不能调用自由的函数

普通对象和常对象对比:
  * 普通对象: 1.可以调用常函数
  *           2.普通函数和常函数可以构成函数的重载(特殊的重载)
  *           3.普通函数和常函数同时存在时,普通的对象首先调用自由的函数
  * 
  * 常对象:  1.只能调用常函数,不能调用自由的函数
  *           2.注意:成员变量要有初值

mutable 关键字
mutable修饰的成员变量可以在常函数中修改
class Person
{
private:
	string name;
	int age;
	mutable int a;
public:
	Person(int age,string name,int a):age(age),name(name),a(a){}
	void show()
	{
		cout<<age<<" "<<name<<endl;
	}
	void show() const
	{
		++a;  //正确,因为被mutable 修饰,在常函数中可以修改值
		cout<<age<<"   "<<name<<"  "<<a<<endl;
	}

4.3 友元(函数、对象)

友元概念:友元可以访问与其好友关系的类中的私有(private)成员,使用friend关键字进行修饰	  
注意: 但友元破坏类的封装特性,慎用!

友元的特点:1、友元是单向的 2、友元不能传递  3、友元不能继承
1)友元是单向的
class B;
class A
{
friend class B;
};
//B是A的友元,但是A不是B的友元。

2)友元不能传递   B是A的友元,C是B的友元,A和C没有友元关系。
3)友元不能继承   

友元分为:友元函数和友元类
1、友元函数(友元全局函数):将普通函数声明为友元函数  friend + 函数声明
#include <iostream>
using namespace std;

//访问好友关系类中的 私有的东西
class Person
{
 //全局函数display是我的朋友
 friend  void display(Person& p);
private:
    int age;
public:
    Person(int age):age(age){}
    void setAge(int age){this->age = age;}
    void show(){cout<<age<<endl;}
};
//全局函数
void display(Person& p)
{
    cout<<p.age<<endl;//12
}
int main()
{
   Person a(12);
   display(a);
    return 0;
}

2、友元类:friend+类声明
#include <iostream>
#include <string>
using namespace std;

class Worker
{
	friend class Student;
};
//类的声明
class Teacher;
class Student
{
friend class Teacher;
private:
	string name;
	int score;
	void sleep()
	{
		cout<<"slepp"<<endl;
	}
public:
	Student(string name, int score):
		name(name),
		score(score)
	{}
};
class Teacher
{
public:
	void look(Student& s)
	{
		cout<<s.name<<" "<<s.score<<endl;
		s.sleep();
	}
};

int main()
{
	Teacher t;
	Student s("小张",19);
	t.look(s);
}

 

 

五、单例模式

1.单例模式的作用与目的
作用:保证一个类仅有一个实例,并提供了一个访问它的全局访问点
目的:为了保证类的实例对象只有一个
主要解决:一个全局使用的类 频繁的创建于销毁
关键: 构造函数和拷贝构造私有化

2、实现方法
1.私有构造函数和拷贝构造函数   不让类的外部创建对象
2.静态类指针     在静态成员函数中实现只创建一个对象的逻辑
3.静态成员函数返回类指针  用来实例化(new)对象

5.1 static(静态成员函数及变量)

c++中静态成员:
1.属于整个类 静态成员变量只存储一份供所有对象使用,所有同类型的对象共享静态变量
2.必须在类外单独初始化 而且只能全局进行 否则不会分配空间 编译报错
#include <iostream>
using namespace std;

class A
{
public:
   static int num;
};
//1.初始化之后,才会对变量分配空间 2.类外进行单独的初始化
int A::num = 10;

int main()
{
    //3.使用静态变量,可以直接只用 类::的方式 获取变量
   cout<<A::num<<endl;
 
    return 0;
}

静态成员函数
没有this指针,所以:
1.静态成员函数不能访问本类中的非静态成员,
2.静态函数只能调用静态成员
3.调用:1.对象可以调用   2.类名直接调用 A::num  A::fun(10);
4.类中普通的函数,可以使用静态变量(共享)
#include <iostream>
using namespace std;

class A
{
public:
   static int num;
   int age;
   A(int n):age(n){}
   static int getNum()
   {
     //静态成员函数没有this指针,就不能使用类中普通的成员变量
     //静态函数只能访问静态的成员变量
     //cout<<this->age<<endl;
        return num;
    }
};
//1.初始化之后,才会对变量分配空间 2.类外进行单独的初始化
int A::num = 10;

int main()
{
    A a(25);
    //3.使用静态变量,可以直接只用 类::的方式 获取变量
   cout<<A::num<<endl;
   cout<<A::getNum()<<endl;//通过类名直接访问静态成员函数
A  s;
cout<<s.get_num()<<endl;//这么写也不算语法错误,但是没有逻辑意义,				因为静态成员函数get_num()中没有指向对象s的指针。
    return 0;
}

5.2 单例模式实现方法

*******************************one.h
#ifndef ONE_H
#define ONE_H

class One
{
    //1.私有构造和拷贝
    One();
    One(const One& other);
    //2.静态指针
    static One* instance;

    int num;
public:
    //3.静态函数:1.创建对象  2.返回静态指针
    //通过静态全局访问口  获取对象指针
    static One* getInstance();

    int getNum()
    {
        num++;
        return num;
    }
    void setNum(int n)
    {
        num = n;
    }

    ~One();
};

#endif // ONE_H

***************************cpp	
#include "one.h"
#include <cstdio>

//cpp文件 进行初始化
One* One::instance = NULL;

One::One(){ num = 1;}
One::One(const One &other){}

One *One::getInstance()
{
    if(instance == NULL)
        instance = new One;
   return instance;
}

One::~One()
{
    if(instance != NULL)
        delete instance;
}

*******************************main
#include <iostream>
#include "one.h"
using namespace std;
/*
 * 设计模式之单例模式

1.单例模式的作用与目的
    作用:保证了一个类仅有一个实例,并提供了一个访问它的全局访问点
    目的:为了保证类的实例对象只有一个
    主要解决:一个全局使用的类 频繁的创建于销毁
    关键: 构造函数和拷贝构造私有化
2、实现方法
    1.私有构造函数和拷贝构造函数   不让类的外部创建对象
    2.静态类指针     在静态成员函数中实现只创建一个对象的逻辑
    3.静态成员函数返回类指针  用来实例化(new)对象
 * */
int main()
{
  One* o1 = One::getInstance();
  o1->setNum(10);
  One* o2 = One::getInstance();
  One* o3 = One::getInstance();

  cout<<o1<<" "<<o2<<" "<<o3<<endl;
  cout<<o2->getNum()<<endl;
  cout<<o3->getNum()<<endl;

    return 0;
}

六、重载(遮蔽)

运算符重载:运算符重载本质是函数重载,函数名以运算符的形式来命名,调用函数也是通过运算符来调用
作用:如果类没有重载运算符,类的对象不能进行运算符的操作

1、定义
1.重载:给运算符重新赋予新的含义,在类的内部定义的运算符重载和成员函数是一样的
2.重载方法:定义一个重载运算符的函数 在需要执行被重载的运算符时,系统会自动调用该函数;
3.重载运算符格式:
	函数类型 operator 运算符名称(形参列表) 
	bool     operator     ==   (const Person &s);	
4.运算符重载的参数个数由运算符本身决定,但是类型可以自定义 
5.由运算符的左值调用运算符的重载
6.如果类没有重载运算符,类的对象不能进行运算符的操作
注意:可以将函数的重载定义成全局的,但是不方便 <<  >>
void operator+(const pereson  other)
{
}
person p;
person p2;
p.operotor+(p2);成员函数一样  普通的调用
p+p2;自动调用

运算符重载虽然对返回值类型和参数类型没有要求,但是我们依然不能随便定义;返回值类型和参数的类型一定要符合习惯才能让代码变得更优雅。

6.1 运算符重载(+ >= ==  与=  & )

****************代码示例1:+号的重载**************
#include <iostream>
using namespace std;

class Person
{
    int age;
public:
    Person(int age):age(age){}
    void show(){    cout<<age<<endl;    }
//运算符重载函数 +
//this是运算符的左值,参数是运算符的右值
    void operator +(Person& other)//p2
    {
        int res = this->age+other.age;
        cout<<res<<endl;
    }
};
int main()
{
   Person p1(12);
   Person p2(4);
   //调用成员函数
 //  p1.operator +(p2);
   //1.左侧调用运算符  右侧为参数
   p1+p2;//自动调用 运算符重载
   p2+p1;
    return 0;
}
**************示例代码2:>=运算符**************
#include <iostream>
using namespace std;
 
class Person
{
public:
	int _age;
	Person(int age):_age(age)
	{
	}
	int operator >=(Person& other)
	{
    		if(this->age>other.age)
         		return 1;
    		else
         		return 0;
 	}
};

int main()
{
	Person per1(14);
	Person per2(6);
	cout << (per1 >= per2) << endl;
	return 0;
}
**************示例3:==运算符重载**************
#include<iostream>
using namespace std;

class Person
{
private:
	int age;
public:
	Person(int a)
	{
		age = a;
	}
	bool operator==(const Person &s);	//==运算符的重载 
};
//this是运算符的左值,参数是运算符的右值
bool Person::operator==(const Person &s)
{
	if(this->age==s.age)
	{
		return true;
	}
	else 
	{
		return false;
	}
}

int main()
{
	Person p1(20);
	Person p2(20);
	if(p1==p2)//这里之所以能够使用==运算符,是因为Person重载了==运算符
	{
		cout<<"the age is equal!"<<endl;
	}
	else 
	{
		cout<<"not equal"<<endl;
	}
}
*****************类型自定义 代码示例4:int、String类型*************
#include <iostream>
using namespace std;

class Person
{
    int age;
    string name;
public:
    Person(int a):age(a)
    {
    }
    Person(string name,int a):name(name),age(a)
    {
    }
   bool operator == (Person& other);
   bool operator == (int a);
   bool operator == (string n);
};
bool Person::operator ==(Person& other)
{
       if(this->age == other.age)
           return true;
       else
           return false;
}
bool Person::operator ==(string n)
{
    if(this->name == n)
        return true;
    else
        return false;
}
bool Person::operator ==(int a)
{
    if(this->age == a)
        return true;
    else
        return false;
}

int main()
{
    Person p(10);
    Person p1(20);

   if(p == p1)//p.operator==(p1)
   {
       cout<<"equal"<<endl;
   }
   else
       cout<<"not"<<endl;

   if(p == 10)
   {
        cout<<"equal int....."<<endl;
   }else
       cout<<"not"<<endl;

   Person p3("tom",25);
   if(p3 == "hello")
   {
       cout<<"equal string..."<<endl;
   }else
       cout<<"not"<<endl;
    return 0;
}

*****************示例5:重载赋值运算符*******************
#include <iostream>
using namespace std;

class Person
{
    int age;
    string name;
public:
    Person(int a):age(a){
        cout<<"构造"<<endl;
    }
    Person(string name,int a):name(name),age(a)
    {}
    Person(const Person& o){
        cout<<"拷贝"<<endl;
    }
   void operator=(Person& other){
        cout<<"=重载"<<endl;
        this->age = other.age;
    }
   void show(){
       cout<<age<<endl;
   }
};
int main()
{
    Person p(10);
    Person p1(20);

    Person p2(p);//创建新对象,拷贝
    p = p1;//两个已经存在的对象,调用赋值运算符的重载

    p.show();
    p1.show();
    return 0;
}

总结
1)必须重载和默认赋值运算符相同类型的参数(对象的引用),才能覆盖掉默认的赋值运算符
2)自己重载了 系统的重载是否还在?
    系统的还在 因为我们重载的赋值运算符的参数和c++默认生成的不一样,所以不会覆盖掉默认赋值运算符的重载
3)要求会写   在写出来一个系统默认的例子,写个和系统一样的  怕面试和笔试题题的时候 问
	Person& operator = (const Person& other )
    {
        this->age = other.age;
        cout<<"赋值运算符的重载"<<endl;
        return *this;
    }
  4)赋值运算符是算浅拷贝 没有特殊需求 是不用覆盖系统默认的

6.2  默认存在函数(5) 与 不可重载运算符(5)

C++默认存在的函数
1)默认构造函数
2)默认拷贝构造函数
3)析构函数
4)默认=重载  
5)默认&重载   这是一个有争议的运算符重载。说它存在因为每个对象都能取地址;说它不存在没人会去重载取地址运算符。面试的时候就说它&是默认存在,知道就比不知道好。

不能重载的运算符 5个  
 ?:   sizeof()   . (成员运算符)  ::    .*  ->* (成员指针运算符)



示例7:&运算符
#include <iostream>
using namespace std;
 
class Person
{
public:
	int _age;
	Person(int age):_age(age)
	{
	}
	//以下的两个&重载函数,只能保留其一,因为不能构成函数的重载
	int* operator & ()
	{
		return &this->_age;
	}
	Person* operator&()
    	{
       	 	return this;
    	}
};
int main()
{
	Person per1(14);
	int *p = &per1;
	cout << p << endl;
	return 0;
}


++ -- 运算符重载
默认情况下为前缀形式 operator++(  )    前缀++p 
后缀形式需要添加一个int类型参数,参数无意义,
仅仅用于区分前缀和后缀形式  operator++(int a)  后缀p++
#include <iostream>
using namespace std;

class Person
{
private:
	int age;
public:
	Person(int age):age(age){}	
	Person& operator++()
	{
		cout<<"前缀形式"<<endl;
		++age;
		return *this;
	}
	Person& operator++(int a)
	{
		cout<<"后缀形式"<<endl;
		age++;
		return *this;
	}
	void show()
	{
		cout<<age<<endl;
	}
};
int main()
{
	Person p(19);
	(p++).show(); //后缀形式,返回值为对象的引用,对象本身
	++p;//前缀形式
}

总结

这里对文章进行总结:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值