C++入门知识(二)——构造函数、析构函数、静态成员、友员函数

一、构造函数/析构函数

1、构造函数

构造函数 ,是一种特殊的方法,类提供的构造函数可自动完成对象的初始化任务。

用途:

在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。

其他:

1、一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。
2、对象有默认的构造函数,一旦实现了自己的构造函数就必须自己实现默认构造函数。
3、构造顺序,对于类中:类中含有对象成员时,先调用对象成员的默认构造函数,再调用类的构造函数。对于多个对象:按运行中定义对象的顺序调用构造函数,静态对象只调用一次构造函数; 全局对象在main函数执行前被构造

函数形式:

一般:
构造函数无返回值,函数名与类名相同,可有参数
“类名()”、"类名(int a = 1)"等
特殊:
拷贝构造函数
Person(const Person & s)

2、析构函数

析构函数(destructor) 与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数。

用途:

析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。

其他:

一个类只能有1个构造函数

函数形式:

析构函数无返回值,函数名在类名前加~,无参数
“~类名()”

例子:
#include <iostream>
using namespace std;
class Person{
private:
	int age;
	const char* name;
public:
	/*构造函数*/
	Person(){
		cout << "Person in" << endl;
	}
	/*析构函数*/
	~Person(){
		cout << "Person out" << endl;
	}
	void setName(const char *name){
		this->name = name;
	}
	int setAge(int age){
		if(age>0&&age<200){
			this->age = age;
			return 0;
		}else 
			cout << "age error!" << endl;
		return -1;
	}
	void printInfo(void){
		cout << "name:" << name <<", age:" << age << endl;
	}
};
int main(int argc,char** argv)
{
	Person zhangsan;
	zhangsan.setAge(50);
	zhangsan.setName("zhangsan");
	zhangsan.printInfo();
}

在这里插入图片描述
对于构造函数还有一种特殊的存在:

3、拷贝构造函数

默认的拷贝构造函数使用:

#include<iostream >
using namespace std;
class Complex
{
public:
    double real, imag;
    Complex(double r, double i) {
        real= r; imag = i;
    }
};
int main(){
    Complex cl(1, 2);
    Complex c2 (cl);  //用复制构造函数初始化c2
    cout<<c2.real<<","<<c2.imag;  //输出 1,2
    return 0;
}

拷贝构造函数可以自己提供,如果编写了复制构造函数,则默认复制构造函数就不存在了,如下为使用自己编写的拷贝构造函数

#include<iostream>
using namespace std;
class Complex{
public:
    double real, imag;
    Complex(double r,double i){
        real = r; imag = i;
    }
    Complex(const Complex & c){
        real = c.real; imag = c.imag;
        cout<<"Copy Constructor called"<<endl ;
    }
};
int main(){
    Complex cl(1, 2);
    Complex c2 (cl);  //调用复制构造函数
    cout<<c2.real<<","<<c2.imag;
    return 0;
}

二、静态成员、友员函数

1、静态成员

静态成员产生的原因是因为类需要对于一些数据进行收集,仅仅类有一份,其他对象没有,如:创造了多少的对象,在类中可设置一个cnt来统计。对于这个cnt就需要使用static来修饰,static cnt就是一个静态成员。
静态成员分为数据成员成员函数

静态数据成员

类中定义类外分配空间和初始化,初始化时不加static

静态成员函数

类外定义不加static,不能访问非static成员

#include <iostream>
#include <string.h>
#include <unistd.h>
using namespace std;
class Person {
private:
	static int cnt;/*静态数据成员*/
	char *name;
	int age;
	char *work;
public:
	static int getCount(void); /*静态成员函数*/
	Person() {
		name = NULL;
		work = NULL;
		cnt++;
	}
	Person(char *name) 
	{
		this->name = new char[strlen(name) + 1];
		strcpy(this->name, name);
		this->work = NULL;
		cnt++;
	}
	Person(char *name, int age, char *work = "none") 
	{
		cout <<"Pserson(char*, int), name = "<<name<<", age= "<<age<<endl;
		this->age = age;
		this->name = new char[strlen(name) + 1];
		strcpy(this->name, name);
		this->work = new char[strlen(work) + 1];
		strcpy(this->work, work);
		cnt++;
	}
	Person(Person &per) 
	{
		cout <<"Pserson(Person &)"<<endl;
		this->age = per.age;
		this->name = new char[strlen(per.name) + 1];
		strcpy(this->name, per.name);
		this->work = new char[strlen(per.work) + 1];
		strcpy(this->work, per.work);
		cnt++;
	}
	~Person()
	{
		cout << "~Person()"<<endl;
		if (this->name) {
			cout << "name = "<<name<<endl;
			delete this->name;
		}
		if (this->work) {
			cout << "work = "<<work<<endl;
			delete this->work;
		}
	}
	void setName(char *n)
	{
		name = n;
	}
	int setAge(int a)
	{
		if (a < 0 || a > 150)
		{
			age = 0;
			return -1;
		}
		age = a;
		return 0;
	}
	void printInfo(void)
	{
		//printf("name = %s, age = %d, work = %s\n", name, age, work); 
		cout<<"name = "<<name<<", age = "<<age<<", work = "<<work<<endl;
	}
};
int Person::cnt = 0; /*类外分配空间和初始化*/
/*类外定义不加static*/
int Person::getCount(void) 
{ 
	return cnt; 
}
int main(int argc, char **argv)
{
	Person p[100];
	cout << "person number = "<<Person::getCount()<<endl;
	cout << "person number = "<<p[0].getCount()<<endl;
	cout << "person number = "<<p[1].getCount()<<endl;
	return 0;
}
2、友员函数

在类中声明非成员函数时加上friend,友员函数可以访问类的私有数据成员
补充“”一个类的成员函数也可以是另一个类的友元。

不使用友员函数
#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Point {
private:
	int x;
	int y;

public:
	Point() {}
	Point(int x, int y) : x(x), y(y) {}

	int getX(){ return x; }
	int getY(){ return y; }
	void setX(int x){ this->x = x; }
	void setY(int y){ this->y = y; }
	void printInfo()
	{
		cout<<"("<<x<<", "<<y<<")"<<endl;
	}
};

Point add(Point &p1, Point &p2)
{
	Point n;
	n.setX(p1.getX()+p2.getX());/*不使用友员函数,访问类的私有成员过于麻烦*/
	n.setY(p1.getY()+p2.getY());/*不使用友员函数,访问类的私有成员过于麻烦*/
	return n;
}

int main(int argc, char **argv)
{
	Point p1(1, 2);
	Point p2(2, 3);

	Point sum = add(p1, p2);
	sum.printInfo();

	return 0;
}
使用友员函数
#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Point {
private:
	int x;
	int y;

public:
	Point() {}
	Point(int x, int y) : x(x), y(y) {}

	int getX(){ return x; }
	int getY(){ return y; }
	void setX(int x){ this->x = x; }
	void setY(int y){ this->y = y; }
	void printInfo()
	{
		cout<<"("<<x<<", "<<y<<")"<<endl;
	}
	friend Point add(Point &p1, Point &p2);/*在类中什么类的友员函数*/
};

Point add(Point &p1, Point &p2)
{
	Point n;
	n.x = p1.x+p2.x;/*使用友员函数,可以直接访问类的私有成员*/
	n.y = p1.y+p2.y;/*使用友员函数,可以直接访问类的私有成员*/
	return n;
}

int main(int argc, char **argv)
{
	Point p1(1, 2);
	Point p2(2, 3);

	Point sum = add(p1, p2);
	sum.printInfo();

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值