[C++的类和对象二]

1.初始化列表

用于多个对象构造,构造函数和其他函数不同,除了有名字、参数、函数体之外还能有初始化表。

简单使用:

class Person
{
private:
	int m_a;
	int m_b;
	int m_c;
public:
	Person(int a, int b, int c) :m_a(a), m_b(b), m_c(c) {}
};

对象作为成员:

class A
{
private:
	int m_a;
public:
	A(int a) :m_a(a) { cout << "A的有参构造"<<endl; }
	~A(){ cout << "A的析构" << endl; }
};

class B
{
private:
	int m_b;
public:
	B(int b) :m_b(b) { cout << "B的有参构造" << endl; }
	~B() { cout << "B的析构" << endl; }
};

class Person
{
private:
	A oba;
	B obb;
public:
	Person(int a, int b) :oba(a), obb(b) { cout << "Person的构造" << endl; }
	~Person(){ cout << "Person的析构" << endl; }
};

void test01()
{
	Person ob1(10, 20);
}

可以看到按对象成员在类中的定义依次调用他们的构造函数,再调用该类的构造函数,最后先进后出析构。

2.explicit关键字

explicit关键字,禁止通过构造函数进行隐式转换。声明为explicit的构造函数不能在隐式转换中使用

class B
{
private:
	int m_b;
public:
	explicit B(int b) :m_b(b) { cout << "B的有参构造" << endl; }
	~B() { cout << "B的析构" << endl; }
};


void test01()
{
	B ob1 = 10;   //错误
	B ob2(10);	   //对
}

3.new和delete

3.1和malloc、calloc及reallocation(下面写mcr)比较

(1)mcr返回一个void指针,c++不允许void赋值给其他指针,必须要强制转换。

(2)mcr可能声情内存失败,所以必须判断返回值确保内存分配成功。

(3)mcr不会调用构造函数,free不会调用析构函数。

(4)mcr,free和new,delete不能混搭使用。

3.2new申请基本类型空间

void test01()
{
	int *p = NULL;
	p = new int;
	*p = 100;
	cout << *p << endl;
	p = new int(200);
	cout << *p << endl;
	delete p;
}

3.3new申请基本类型数组空间

void test02()
{
	int *arr = NULL;
	arr = new int[5]{1,2,3,4,5};  //定义+初始化
	for (int i = 0; i < 5; i++)
	{
		cout << *(arr + i) << ' ';
	}
    delete[]arr;
}
void test03()
{
	char *arr = NULL;
	arr = new char[32];
	strcpy(arr, "lingo");
	cout << arr << endl;
	delete[]arr;
}

注意:申请时new加[],释放时delete加[]。

3.4new申请类对象空间

class Person
{
private:
	int m_num;
	char *arr = new char[32];
public:
	Person()
	{
		cout << "默认构造函数" << endl;
	}

	Person(const char *name, int num)
	{
		m_num = num;
		strcpy(arr, name);
	}

	~Person()
	{
		cout << "析构函数" << endl;
	}
};
void test04()
{
	Person *p = new Person("lingo",20);
	delete p;
}
void test05()
{
	Person *p = new Person;
	delete p;
}

new按照Person申请空间,如果申请成功就会自动调用Person类的构造函数

delete先调用析构函数,再释放堆区空间

4.对象数组

本质是数组,但成员是对象。

Person arr1[5];
Person arr2[5]={Person("lingo",20),Person("lucy",18)};

定义数组时,系统会自动给数组的每个元素调用构造函数

用new申请对象数组

Person *arr=NULL;
arr = new Person[5]{};
delete []arr

5.静态成员(static修饰的成员)

static修饰的成员为静态成员,不管这个类创建了多少对象,静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。

静态成员属于类而不对象。

5.1static修饰成员变量

静态变量再编译阶段就会分配内存空间,对象还没有创建时,就已经分配内存空间。

静态成员必须在类中声明,类外定义。

class Person
{
public:
	int num;
	static int data;
};
int Person::data = 10;

void test01()
{
	cout << Person::data << endl;
	Person::data = 20;
	cout << Person::data << endl;
	Person ob1;
	ob1.data = 30;
	cout << Person::data << endl;
}

int main()
{
	test01();
}

5.2静态成员函数

data静态,在创建对象之前就存在,如果没有实例化对象,却想使用data,就要用到静态成员函数。

class Person
{
private:
	static int data;
public:
	static int getData()
	{
		return data;
	}
};
int Person::data = 10;

void test01()
{
	cout << Person::getData() << endl;
}

注意:

(1)静态成员函数的目的是操作静态成员数据

(2)静态成员函数不能访问非静态成员数据。(静态成员函数内部没有this指针)

(3)普通成员函数可以操作静态成员数据和非静态成员数据。

5.3const修饰静态成员

如果一个类的成员既要实现共享,又要实现不可改变,就可以使用static const 修饰。

class Person
{
private:
	const static int data;
public:
	const static int getData()
	{
		return data;
	}
	
};
const int Person::data = 10;   //const不能省略

void test01()
{
	cout << Person::getData() << endl;
}

5.4两个案例

5.4.1静态成员统计类的实例化对象的个数

class Person
{
public:
	static int count;
	Person()	//无参构造
	{
		count++;
	}
	Person(Person *ob)	//拷贝构造
	{
		count++;
	}
	~Person()
	{
		count--;
	}
};
int Person::count = 0;   

void test01()
{
	cout << "现存对象数:" << Person::count << endl;
	Person ob1;
	cout << "现存对象数:" << Person::count << endl;
	{
		Person ob2;
		Person ob3;
		cout << "现存对象数:" << Person::count << endl;
	}
	cout << "现存对象数:" << Person::count << endl;
}

5.4.2单例模式设计——打印机

步骤一:在单例类内部定义一个singleton类型的静态对象,作为外部共享的唯一实例

步骤二:提供一个公共静态的方法,让客户可以访问它的唯一实例

步骤三:为了防止外部实例化其他对象,将其构造函数设计为私有

class Printer
{
private:
	static Printer *singlePrint;        //创建这个类的唯一一个对象
	Printer() { count = 0; }            //私有化构造函数
	Printer(const Printer &ob){}
public:
	int count;
	static Printer* getSPrint()        //提供这个对象的访问方法
	{
		return singlePrint;
	}
	void printText(const char *str)    //功能实现
	{
		cout << "打印" << str << endl;
		count++;
	}
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值