小技巧:能用组合,不用继承
以另一个类的对象为数据成员
组合类的对象,写构造函数,必须采用初始化参数列表的写法
对于组合类的构造函数
~要为自己的属性初始化--->初始化参数列表,this指针
~为组合类的对象做初始化<--->必须采用初始化参数列表的方式调用分支类的构造函数
MM类以boy类的对象为数据成员
#include <iostream>
using namespace std;
class Boy
{
public:
Boy(string name, int age) :name(name), age(age) {} /*要有两个参数的构造函数*/
void print()
{
cout << name << "\t" << age << endl;
}
protected:
void printData()
{
cout << name << "\t" << age << endl;
}
string name;
int age;
};
class MM
{
public:
MM(string boyName, int boyAge, string mmName) :boy(boyName, boyAge) /*boyName,boyAge 给boy初始化,决定了组合类必须具有和分支类形态一致的构造函数*/
{
this->mmName = mmName;
}
MM(string mmName) :mmName(mmName), boy("默认", 18) {}
void print()
{
boy.print();
/*boy.printData(); 不可访问,boy对象对于Boy类是类外,不可直接访问保护
属性下的数据成员、成员函数*/
cout << mmName << endl; //访问自己的属性
}
protected:
string mmName;
Boy boy; //MM类以boy类的对象为数据成员,这里不能构造有参对象,只能定义一个对象
};
int main()
{
MM mm("boy", 18, "mm");
mm.print();
return 0;
}
注意事项
boy对象想访问Boy里面属性也受权限限定,不能直接打印--->需要提供接口
构造顺序问题
与初始化参数列表无关,只与对象的定义顺序有关
~析构顺序和构造顺序相反
A、B、C类组成D类
#include <iostream>
using namespace std;
class A
{
public:
A(string str) :str(str)
{
cout << str;
cout << "1";
}
string str;
};
class B
{
public:
B(string str) :str(str)
{
cout << str;
cout << "2";
}
string str;
};
class C
{
public:
C(string str) :str(str)
{
cout << str;
cout << "3";
}
string str;
};
class D
{
public:
D(string stra, string strb, string strc) :b(strb), c(strc), a(stra) /*初始化参数列表
分别调用它们的构造函数*/
{
cout << "D";
cout << "4";
}
A a; //3个对象
C c;
B b;
};
int main()
{
D d("A", "B", "C");
return 0;
}
//输出:A1C3B2D4
类中类
定义在另一个类中的类
ps:sto中有大量的类中类
类中类也受权限限定
如何访问?如何通过类中类打印数据?---->需要类名限定,用前缀的方式访问
#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;
}
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()
{
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;
}
return 0;
}
类中的枚举
是否受权限限定?如何访问枚举类型?
//类中枚举类型
class A
{
public:
enum time {first,second};
protected:
enum date {mon,sur,tus}; //类中的枚举类型受权限限定
};
int main(){
mon;//直接访问有问题,需要用类名限定去访问
//cout << A::date::mon << endl; 有权限限定问题,不可直接访问
cout << A::time::first << endl; //public属性访问可以直接访问
}
小知识:
除了友元函数不属于类,不受权限限定--->其他类中的属性都受权限限定(protected、private)
类中默认的函数
构造函数、析构函数、拷贝构造函数、赋值运算重载
#include <iostream>
using namespace std;
class A
{
public:
A() = default;
A(A& object) = default;
A& operator=(A& object) = default; //返回类型是对对象的引用
~A() = default;
};
int main()
{
A a;
A b = a;
A c;
c = a; //赋值运算重载
return 0;
}
普通函数没有默认函数
//void print() = default; 是错误的