在实际不使用该类型的类中输入所需的信息

时间:2016-10-27 18:20:59

标签: c++ c++11 move-semantics

所以我有以下文件,其中包含以下内容:

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) 的更多信息?实际发生了什么?我认为这是非常模糊的,很难遵循。我该如何避免这种情况?最初的例子更复杂,所以我不得不实际挖掘和简化这个。我只想尝试一个只有必要信息的最小头文件,避免不必要的宏扩展。

2 个答案:

答案 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));
}

这个编译,链接并运行得很好