类的组合描述的是一个类内嵌其他类的对象作为成员的情况,它们之间的关系是一种包含与被包含的关系
class Engine {
public:
void start() {
// 启动引擎的逻辑
std::cout << "Engine started!" << std::endl;
}
// ... 其他引擎相关的方法 ...
};
class Car {
private:
Engine engine; // Car类包含一个Engine类的对象作为成员
public:
void startCar() {
engine.start(); // 调用Engine对象的start方法
// ... 其他启动汽车的逻辑 ...
}
// ... 其他汽车相关的方法 ...
};
int main() {
Car myCar;
myCar.startCar(); // 输出:Engine started! ...(其他启动汽车的逻辑)
return 0;
}
注意:
若创建类的对象时,此类中具有内嵌对象成员,那么各个内嵌对象将被自动创建
在创建对象是要对内嵌对象成员进行初始化
class Inner {
public:
int value;
Inner(int v) : value(v) {} // Inner类的构造函数
};
class Outer {
public:
Inner innerObj;
Outer(int v) : innerObj(v) {} // 使用初始化列表初始化innerObj
};
int main() {
Outer outer(10); // 创建一个Outer对象,并使用10来初始化其innerObj成员
// 此时outer的innerObj的value成员已经被初始化为10
}
聚合初始化(C++11及以后版本):
对于聚合类型(没有用户定义的构造函数、没有私有或保护的非静态数据成员、没有基类也没有虚函数的类),可以使用聚合初始化来初始化成员。
#include<iostream>
using namespace std;
class Inner {
public:
int value;
};
class Outer {
public:
Inner innerObj;
void coutt()
{
cout<<innerObj.value;
}
};
int main() {
Outer outer = {Inner{10}}; // 使用聚合初始化来初始化outer的innerObj成员
// 此时outer的innerObj的value成员已经被初始化为10
outer.coutt();
}
组合类构造函数的定义一般形式:
类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表){
类的初始化
}
对基本数据成员也可以定义为
A::A(int a):r(a){} r基本数据成员
调用内嵌构造函数顺序:按内嵌对象定义的顺序调用
注意:在构造函数中出现的顺序和调用顺序无关
#include <iostream>
class Inner1 {
public:
Inner1() { std::cout << "Inner1 constructor\n"; }
};
class Inner2 {
public:
Inner2() { std::cout << "Inner2 constructor\n"; }
};
class Outer {
public:
Inner1 inner1;
Inner2 inner2;
Outer() : inner2(), inner1() { // 初始化列表中的顺序与构造函数的调用顺序无关
// 注意:即使这里inner2在inner1之前,但inner1的构造函数仍然会先被调用
}
};
int main() {
Outer outer; // 构造Outer对象
return 0;
}
输出结果
Inner1 constructor
Inner2 constructor
若有些对象为出现在构造函数中,也会被调用:
#include <iostream>
class Inner1 {
public:
Inner1() { std::cout << "Inner1 constructor\n"; }
};
class Inner2 {
public:
Inner2() { std::cout << "Inner2 constructor\n"; }
};
class Outer {
public:
Inner1 inner1;
Inner2 inner2;
Outer() {
// 注意:没有在初始化列表中明确列出inner1和inner2
// 但它们的构造函数仍然会按照声明顺序被调用
}
};
int main() {
Outer outer; // 构造Outer对象
return 0;
}
输出结果
Inner1 constructor
Inner2 constructor
#include <iostream>
class Inner {
public:
Inner() { std::cout << "Inner constructor\n"; }
~Inner() { std::cout << "Inner destructor\n"; }
};
class Outer : public Base { // 假设有一个基类Base
public:
Inner inner1;
Inner inner2;
Outer() {
std::cout << "Outer constructor\n";
}
~Outer() {
std::cout << "Outer destructor\n";
}
};
class Base {
public:
Base() { std::cout << "Base constructor\n"; }
~Base() { std::cout << "Base destructor\n"; }
};
int main() {
Outer outer;
return 0;
}
Base constructor // 基类构造函数
Inner constructor // 成员inner1的构造函数
Inner constructor // 成员inner2的构造函数
Outer constructor // 当前类Outer的构造函数
Outer destructor // 当前类Outer的析构函数
Inner destructor // 成员inner2的析构函数(逆序)
Inner destructor // 成员inner1的析构函数(逆序)
Base destructor // 基类析构函数
组合类的复制构造函数
Outer(const Outer& other) : inner1(other.inner1), inner2(other.inner2){}
#include <iostream>
class Inner {
public:
int value;
Inner(int v = 0) : value(v) {
std::cout << "Inner constructor with value " << value << std::endl;
}
Inner(const Inner& other) : value(other.value) {
std::cout << "Inner copy constructor with value " << value << std::endl;
}
// ... 其他成员函数 ...
};
class Outer {
public:
Inner inner1;
Inner inner2;
Outer(int v1 = 0, int v2 = 0) : inner1(v1), inner2(v2) {
std::cout << "Outer constructor" << std::endl;
}
// 复制构造函数
Outer(const Outer& other) : inner1(other.inner1), inner2(other.inner2) {
std::cout << "Outer copy constructor" << std::endl;
}
// ... 其他成员函数 ...
};
int main() {
Outer original(1, 2); // 调用Outer和Inner的构造函数
Outer copy = original; // 调用Outer的复制构造函数,它会调用Inner的复制构造函数
return 0;
}
Inner constructor with value 1
Inner constructor with value 2
Outer constructor
Outer copy constructor
Inner copy constructor with value 1
Inner copy constructor with value 2