所以我有以下文件,其中包含以下内容:
a.h:
#ifndef A_H
#define A_H
class A {
};
#endif
b.h:
#ifndef B_H
#define B_H
#include <memory>
class A;
class B {
public:
B(std::unique_ptr<A> a);
private:
std::unique_ptr<A> a_;
};
#endif
b.cpp:
#include "b.h"
#include "a.h"
B::B(std::unique_ptr<A> a) : a_(std::move(a)) {
}
c.h:
#ifndef C_H
#define C_H
#include "b.h"
class C {
public:
void add_b(std::unique_ptr<B> b);
private:
std::unique_ptr<B> b_;
};
#endif
c.cpp:
#include "c.h"
void C::add_b(std::unique_ptr<B> b) {
b_ = std::move(b);
}
包含空主方法的文件。正如你在b.h
中看到的那样,我实际上并不包括a.h
,因为我只在类声明中使用指针并且没有必要,只有一个声明就足够了 - class A;
。如果我尝试使用gcc编译它,我会收到类似以下内容的错误:
在/ usr / include / c ++ / 5 / memory:81:0中包含的文件中, 从b.h:4, 来自c.h:4, 来自c.cpp:1: 错误:'sizeof'无效应用于不完整类型'A'
static_assert(的sizeof(_TP)大于0
当我看到&#34;不完整类型的部分&#39; A&#39;&#34;我发现class C
需要有关A
的更多信息,因为它不知道它的存在,因为它只包括b.h
只使用了class A;
A(a.h
)的声明。显然,在c.cpp
中包含A
标头可以解决错误,但后来我意识到C
实际上并没有参与C
类的可见实现。为什么class A
需要了解有关sentence = input("Please enter a sentence:")
words = sentence.split()
position= [0]
myList = []
[myList.append(x) for x in words if x not in myList]
print(myList)
的更多信息?实际发生了什么?我认为这是非常模糊的,很难遵循。我该如何避免这种情况?最初的例子更复杂,所以我不得不实际挖掘和简化这个。我只想尝试一个只有必要信息的最小头文件,避免不必要的宏扩展。
答案 0 :(得分:2)
然后我意识到A实际上并没有参与C类的可见实现。为什么C需要了解有关A类的更多信息?
要求
class A
执行class B
时需要隐含 std::unique_ptr<B> b_;
class C
<{1>}中的,因此错误。
通过A
的{{1}}部分public
可见class B
并不重要。此时必须完整声明class B
,其中包括class A
的完整声明。
答案 1 :(得分:0)
您收到错误是因为std :: unique_ptr是底层不完整类型A的大小。显然,要获取类型的sizeof,必须定义类型。
unique_ptr是基础类型的大小的原因是std::default_delete<A>
。如果覆盖unique_ptr的默认删除器,则可以使它不会使基础类型的大小变小,并且可以在没有完成类型的情况下进行编译。
示例...
#include <memory>
#include <iostream>
class A;
struct Deleter {
void operator()(A* ptr) const {
std::cout << "I'm supposed to delete A but I'm a liar!" << std::endl;
}
};
int main() {
std::unique_ptr<A, Deleter> a(reinterpret_cast<A*>(1));
}
这个编译,链接并运行得很好