【发布时间】:2019-11-12 16:25:29
【问题描述】:
由于与视频类的循环依赖关系,我正向前声明一个位于另一个命名空间内的类。此类用于存储在 mmu 类中的共享指针。一旦我在类的构造函数中分配了共享指针,它就会出错invalid use of incomplete type ‘using element_type = class graphic::Video {aka class graphic::Video}’
。
mmu.h
#pragma once
#include "../cartridge/cartridge.h"
/* forward decleration */
namespace graphic {
class Video;
}
namespace memory {
class Mmu {
public:
std::shared_ptr<Cartridge> cartridge;
std::shared_ptr<graphic::Video> video;
Mmu(std::shared_ptr<Cartridge>&, std::shared_ptr<graphic::Video>&);
};
}
mmu.cpp
#include <iostream>
#include "mmu.h"
namespace memory {
Mmu::Mmu(std::shared_ptr<Cartridge> &_cartridge, std::shared_ptr<graphic::Video> &_vid)
: video(_vid)
{
video->initializeColorPallete(); //errors
}
调用者.cpp
#include <iostream>
#include <vector>
#include "caller.h"
Caller::Caller(std::vector<uint8_t> cartridgeData)
:cartridge(getCartridge(std::move(cartridgeData))),
cpu(std::make_unique<cpu::CPU>(mmu)),
video(std::make_shared<graphic::Video>(mmu, cpu)),
mmu(std::make_shared<memory::Mmu>(cartridge, video))
{
}
video->initializeColorPallete(); 在构造函数中出错。
【问题讨论】:
-
因为
graphic::Video在调用它的方法时仍然是一个不完整的类型。将实际类包含到您的 cpp 文件中。 -
投票结束是一个错字。您从未将定义
Video的文件包含在mmu.cpp中。 -
除此之外,您还需要在 cpp 中为
std::shared_ptr<graphic::Video>成员定义的类Mmu的析构函数。从声明生成的默认析构函数不知道如何析构graphic::Video对象。 -
用不同的话来说说:前向声明有助于打破头文件中的循环依赖关系,但仍然需要完整的定义才能使用这种类型。编译器如何知道
graphic::Video类型是否有方法initializeColorPallete,它需要多少个参数以及它的返回类型是什么。 -
@parktomatomi 谢谢,但你并没有真正回答我的问题。尝试让班级成员
unique_ptr<T>前向声明T。至少对于当前的 GCC,如果没有声明的析构函数在已知T的某处定义(可以为空),它将无法编译(当类被实例化时)。使用shared_ptr<T>,令我惊讶的是,问题不存在。
标签: c++ smart-pointers forward-declaration