Day 7 C++类的组合和一些默认函数

一、以另一个类的对象作为一个类的数据成员

1.构造函数的写法必须采用初始化参数列表的写法

注意点:①当B类含有数据成员A a;时,此时的a是不能直接初始化的。

②一般在B的构造函数参数中,先写类组合的参数,且在初始化参数列表中用的是调用A的初始化成员列表(A的构造函数的方式)

              ③权限问题:B类中的a对象相对于A类是属于类外的,仅能通过“提供一个接口”去访问protected中的数据成员(函数),但是B类访问自己是不受限制的(如下面B类中的print()函数,通过A类中写好的接口去访问a的数据成员)

#include<iostream>

using namespace std;

class A
{
public:
	A(int id,string name):id(id),name(name) {}
	void print()
	{
		cout <<id <<"\t"<<name << endl;
	}
protected:
	int id;
	string name;
};
class B
{
public:
	B(string Aname,int Aid,int Bnum):a(Aid,Aname),num(Bnum){}
	void print()
	{
		a.print();
		cout << num << endl;
	}
protected:
	
	A a;
	int num;
};

int main()
{
	B b("wbm", 002, 19);
	b.print();
	return 0;
}

2.类的组合构造顺序:

#include<iostream>

using namespace std;

class A
{
public:
	A(int num):num(num)
	{
		cout << "A" ;
	}
	int num;
};
class B
{
public:
	B(int num):num(num)
	{
		cout << "B";
	}
	int num;
};
class C
{
public:
	C(int num):num(num)
	{
		cout << "C";
	}
	int num;
};
class D 
{
public:
	D(int num, int anum, int bnum, int cnum) :num(num), a(anum), b(bnum), c(cnum)
	{
		cout << "D";
	}
protected:
	A a;
	B b;
	C c;
	int num;
};
int main()
{
	D(1, 2, 3, 4);//输出 ABCD 析构函数顺序和他相反
	return 0;
}

总结:构造函数顺序仅和在D类中定义的几个数据成员的顺序有关->析构顺序相反

二、类中类

1.类中的类仍然是要收到权限限定的,且访问的方式需要进行类名限定::

实例:迭代器iterator-->类模仿指针行为(包含指针的前插、打印等以及运算符的重载)

#include<iostream>

using namespace std;
struct Node
{
	int data;
	Node* next;

	Node()
	{
		this->next = nullptr;//创建一个表头
	}
	Node(int data)//新建一个节点
	{
		this->next = nullptr;
		this->data = data;//相当于初始化
	}
};
class List//链表
{
public:
	List()
	{
		headNode = new Node;//调用的struct Node里面的不含参数的初始化——>也就是给了一个nullptr方便后面终止
	}
	void push_front(int data)前插法(头节点始终不变,永远在头节点后面插入一个)
	{
		Node* newNode = new Node(data);
		newNode->next = headNode->next;
		headNode->next = newNode;
	}
protected:
	Node* headNode;
public:
	//迭代器->类模仿指针行为
	class iterator
	{
	public:
		iterator(Node* pMove = nullptr) :pMove(pMove) {}
		void operator=(Node* pMove)//重载=
		{
			this->pMove = pMove;
		}
		bool operator!=(Node* pMove)
		{
			return this->pMove != pMove;
		}
		iterator operator++()//重载前置++
		{
			pMove = pMove->next;//让指针自己移动,切不可新建一个不知道的节点打断整个链表
			return iterator(pMove);
		}
		Node* &operator*()
		{
			return pMove;
		}
	protected:
		Node* pMove;
	};
	Node* begin()//作为遍历的起点,head->next作为起点,不要headNode
	{
		return headNode->next;
	}
	Node* end()
	{
		return nullptr;
	}
};

int main()
{
	List list;
	for (int i = 0; i < 3; i++)
	{
		list.push_front(i);
	}
	List::iterator iter;//相当于一个指针
	for (iter = list.begin(); iter != list.end(); ++iter)
	{
		cout << (*iter)->data;//强烈注意,这边对iter进行解引用后仍然是一个指针。

	}
    return 0;
}

补充:类中对枚举类型的访问方式

也受权限限定,也需要类名限定::

#include<iostream>

using namespace std;

class A
{
public:
	enum week{mon,tus,thus};
private:
	enum time{fisrt,second};
};

int main()
{
	A a;
	cout << A::week::mon;
	//cout << A::time;//不可以访问
	return 0;
}

 三、类中默认的的函数

大致上是四个

#include<iostream>

using namespace std;

class A
{
public:
	A() = default;//默认的构造函数
	A(A& object) = default;//默认的拷贝函数
	A& operator=(const A& a) = default;//默认的重载=
	~A() = default;//默认的析构函数
protected:
	int num;
};
int main()
{
	A wbm;
	A jie(wbm);
	wbm = jie;
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Ocean__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值