类的包含
一个类对象作为另一个类的数据成员
构造顺序
(1)如果作为数据成员的类对象是声明的:A a;
class B{
private:
A a;
};
在创建 B 对象时,先构造 A 的对象 a,再构造 B 的对象,可以直接访问。注意,类的构造是先定义属性,再执行构造方法,如果属性是对象的声明,会一起创建这个对象,它会先看构造函数初始式是否显式声明此对象的构造方法,如果有,调用此构造方法,否则调用默认构造方法,但是前提是此类要存在默认构造方法,在析构的时候按照相反的顺序。
#include<iostream>
using namespace std;
class A{
private:
string s1;
protected:
string s2;
public:
string s3;
A() {
s1 = "A::private";s2 = "A::protected";s3 = "A::public";
cout<<"A build!"<<endl;
}
};
class B{
private:
A a;
int b;
public:
B() {
b = 3;
cout<<"B build!"<<endl;
}
};
int main(){
B b;
}
结果:
A build!
B build!
#include<iostream>
using namespace std;
class Inter{
string name;
public:
Inter(){
name = "inter";
cout<<name<<" of Inter build!"<<endl;
}
Inter(string n){
name = n;
cout<<"Inter use "<<n<<" build!"<<endl;
}
~Inter(){
cout<<name<<" of Inter not build!"<<endl;
}
};
class Base{
Inter inter;
public:
Base():inter("baseInter"){
cout<<"Base build!"<<endl;
}
~Base(){
cout<<"Base not build!"<<endl;
}
};
int main(){
Base b;
}
结果:
Inter use baseInter build!
Base build!
Base not build!
baseInter of Inter not build!
(2)如果作为数据成员的形式是声明指针,那么不会创建 A 对象,需要在 B 的构造函数内部或初始式中 new 出 A 对象,否则不可访问。A* a;
#include<iostream>
using namespace std;
class A{
private:
string s1;
protected:
string s2;
public:
string s3;
A() {
s1 = "A::private";s2 = "A::protected";s3 = "A::public";
cout<<"A build!"<<endl;
}
};
class B{
private:
A* a;
int b;
public:
B() {
b = 3;
cout<<"B build!"<<endl;
a = new A();
}
};
int main(){
B b;
}
结果:
B build!
A build!
访问限制
外部类只可访问内部类对象的 public 成员。
#include<iostream>
using namespace std;
class A{
private:
string s1;
protected:
string s2;
public:
string s3;
A() {
s1 = "A::private";s2 = "A::protected";s3 = "A::public";
cout<<"A build!"<<endl;
}
};
class B{
private:
A a;
int b;
public:
B() {
b = 3;
cout<<"B build!"<<endl;
}
void show(){
cout<<a.s1<<endl; // 错误,不可访问 private
cout<<a.s2<<endl; // 错误,不可访问 protected
cout<<a.s3<<endl; // 正确,只可访问 public
}
};
int main(){
B b;
}