C++类和对象

一、类的定义

(1)格式:

class 类名

{

权限控制符:

        成员;(成员变量\成员函数)

};

(2)权限控制符包括:

        public:成员类内可以访问 类外可以访问、

        protected:成员类内可以访问 类外不可以访问、子类可以访问父类的protected成员

        private: 成员类内可以访问 类外不可以访问 子类不可以访问父类的private成员

(3)在类外实现成员函数,需在返回值类型之后、函数名之前加上所属类作用域即“类名::”

        格式:返回值类型 类名::函数名 (参数列表){函数体}

二、对象的创建与使用

1、定义格式:类名 对象名;

2、对象的成员变量和成员函数的访问可以通过“ . ”运算符实现。

三、this指针

(1)成员变量和成员函数分开存储的

        空对象占内存空间为:1

        静态成员函数、静态成员变量、非静态成员函数都不属于类的对象上;只有非静态成员变量            属于类对象上,占用类对象存储空间

(2)this指针指向被调用的成员函数所属的对象

(3)this用途:1、解决名称冲突this->age=age;

                          2、返回对象本身return *this;

                                Person& PersonAddAge(Person p){

                                        this->age=p.age;

                                        return *this;}

                           注意:返回值类型是引用,如果是值Person,则发生拷贝,this为未进行加运算                                          的原对象

四、构造函数

1、自定义构造函数:完成对象的初始化

注意:(1)如果在类中提供了自定义构造函数,编译器便不再提供默认构造函数

        (2)构造函数没有返回值,不用写void

        (3)函数名与类名相同

        (4)无返回值,有参数,可以重载

        (5)调用默认构造函数时,不要加(),否则编译器会认为是一个函数声明

        (6)编译器自动创建默认构造函数、析构函数、拷贝构造函数;一旦自定义有参构造函数,编译器将不再提供默认构造函数,拷贝构造函数依然提供;一旦自定义拷贝构造函数,编译器将不再提供默认构造函数。

2、自定义无参构造函数、自定义有参构造函数、通过“ :”运算符在构造函数后初始化成员变量

类::构造函数(参数列表):成员变量1(参数一),成员变量2(参数2),....,成员变量(参数n){        构造函数体        }

#include<iostream>
#include<string>
using namespace std;
class Birth{
public:
    Birth(){}//无参构造
	Birth(int year, int month, int day);//有参构造
	void show();
private:
	int _year;
	int _month;
	int _day;
};
//通过“:”初始化
Birth::Birth(int year, int month, int day) :_year(year), _month(month), _day(day)
{
	cout << "Brith类构造方法函数" << endl;
}
void Birth::show(){
	cout << "出生日期" << _year << "-" << _month << "-" << _day << endl;
}

3、拷贝构造函数

(1)格式

构造函数名称(const 类名 & 对象名){        函数体        }

(2)调用时机

        a、使用一个已经创建好的对象来初始化一个新的对象

        b、值传递的方式给函数参数传值

        c、以值的方式返回局部对象

(3)深拷贝与浅拷贝

自己实现拷贝构造函数,解决浅拷贝带来的问题

注:Person成员变量:public:int _age;int *_height;

Person(const Person &p)
{
    cout<<"Person 拷贝构造函数"<<endl;
    _age=p._age;
    //_height=p._height;编译器默认实现这行代码
    //深拷贝操作
    _height = new int(*p._height);
}

4、调用

(1)括号法

        Birth b1;Birth b2(2012,10,2);Birth b3(b2);

(2)显示法

        Birth b1;Birth b2=Birth(2012,10,2);Birth b3=Birth(b2)

(3)隐式转换法

        Birth b3=b2;

五、类对象作为类成员

(1)格式:

        class B {        A a;        ...        }

(2)构造

B(参数列表)::成员变量1(参数1),成员变量2(参数2),... ,a(参数n-1,参数n){ }

B(参数列表)::a(参数n-1,参数n)

{成员变量1= 参数1;   成员变量2 = 参数2;....}

B(参数列表){成员变量1= 参数1;   成员变量2 = 参数2;a.成员变量=参数....}

(3)注意:

当其他类对象作为本类成员,构造是先构造成员变量类对象,再构造自身类对象

                析构顺序与构造顺序相反

六、静态成员static、const修饰成员函数

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

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

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

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

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

常对象只能调用常函数,因为普通成员函数可以修改成员属性

#include<iostream>
using namespace std;
class Person {
public:
	int _A;
	mutable int _B;
	//this指针的本质 是指针常量 指针的指向是不可以修改的
	//const Person * const this;
	//在成员函数后面加const,修饰的是this指向,让指针指向的值也不可以修改
	void showPerson() const 
	{
		this-> _B = 100;
		//this->_A = 100;
		//this = NULL;this指针不可以修改指针的指向
	}

};
void test() {
	Person p;
}
int main(){
	test();
	return 0;
}

七、友元

(1)友元的目的就是让一个函数或类访问另外一个类中的私有成员

(2)友元的关键字friend

(3)友元三种实现:全局函数做友元、类做友元、成员函数做友元

全局函数做友元格式:

class 类名

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

        .....//其他成员

}

类做友元格式:

class B;

class A{};

class B{        friend class A;        };声明A是B的友元类

成员函数做友元格式:

class B;

class A{        public:int func();        };

class B{        friend int A::func();        };声明类A的成员函数func()为友元函数

#include<iostream>
#include<math.h>
using namespace std;

class Point;
class Circle {
private:
	const float PI = 3.14;
public:
	float  getArea(Point& p1, Point& p2);
};
class Point {
	friend float Circle::getArea(Point& p1, Point& p2);
public:
	Point(float x, float y);
	~Point();
private:
	float _x;
	float _y;
};
Point::Point(float x = 0, float y = 0) :_x(x), _y(y) {
	cout << "初始化坐标点" << endl;
}
Point::~Point() {}

float Circle::getArea(Point& p1, Point& p2) {
	float x = abs(p1._x - p2._x);
	float y = abs(p1._y - p2._y);
	float len = sqrtf(x * x + y * y);
	cout << "获取两个坐标点之间的距离是" << len << endl;
	return len * len * PI;
}
int main() {
	Point p1(5, 5);
	Point p2(10, 10);
	Circle circle;
	float area = circle.getArea(p1, p2);
	cout << "圆的面积是" << area << endl;
	system("pause");
	return 0;

}

八、运算符重载

(1)加法运算符重载格式:

返回值类型 operater运算符 (参数列表){        函数体        。。。}

双目运算符重载后调用格式

左操作数.运算符重载函数名(右操作数)注a1+a2相当于a1.operater+(a2);

(2)左移运算符重载,

只能利用全局函数重载左移运算符,访问私有成员需要友元

格式:ostream& operator<<(ostream& 别名,const 类对象引用);

           istream& operator>>(istream& 别名,类对象引用);

(3)递增运算符重载

单目运算符重载后调用格式

前置递增返回值是引用

后置递增返回值是值

#include<iostream>
using namespace std;

class MyInteger {
friend ostream& operator<<(ostream& out, MyInteger myint);
private:
	int _Num;
public:
	MyInteger() {
		_Num = 0;
	}
	//前置运算符 返回引用为了一直对一个数据进行递增操作
	MyInteger& operator++() {
		_Num++;
		return *this;
	}
	//后置运算符 
	MyInteger operator++(int) {
		MyInteger temp = *this;
		_Num++;
		return temp;
	}
};
ostream& operator<<(ostream& out, MyInteger myint) {
	out << myint._Num;
	return out;
}
void test01() {
	MyInteger myint;
	cout << ++(++myint) << endl;
	cout << myint << endl;
}
void test02() {
	MyInteger myint;
	cout << myint++ << endl;
	cout << myint << endl;
}
int main() {
	test01();
	test02();
	system("pause");
	return 0;

}

(4)赋值远算符重载

#include<iostream>
using namespace std;

class Person {
public:
	Person(int age) {
		_age = new int(age);
	}
	//重载赋值运算符
	Person& operator=(Person& p)
	{
		if (_age != NULL) {
			delete _age;
			_age = NULL;
		}
		//提供深拷贝 解决浅拷贝重复释放的问题
		_age = new int(*p._age);
		//返回引用本身,可以进行重复赋值操作
		return *this;
	}
	~Person() {
		if (_age != NULL) {
			delete _age;
			_age = NULL;
		}
	}

	int *_age;
};
void test01() {
	Person p1(18);
	Person p2(20);
	Person p3(30);
	p3 = p2 = p1;
	cout << "p1的年龄:" << *p1._age << endl;
	cout << "p2的年龄:" << *p2._age << endl;
	cout << "p3的年龄:" << *p3._age << endl;
}
int main() {
	test01();
    return 0;
}

(5)关系远算符重载

bool operator运算符(参数列表){        函数体        ....}

(6)仿函数(重载小括号)

#include<iostream>
using namespace std;

class MyAdd {
public:
	int operator()(int v1, int v2)
	{
		return v1 + v2;
	}
};
void test02() {
	MyAdd add;
	int ret = add(10, 10);
	cout << "ret=" << ret << endl;
	//匿名对象调用MyAdd()
	cout << "MyAdd()(100,100)=" << MyAdd()(100, 100) << endl;
}
int main() {
	test02();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值