类体内的前向声明是否被视为其他类型?

时间:2019-05-23 23:35:14

标签: c++ c++11 inner-classes forward-declaration

我在一个封闭类中有两个内部结构,在其中一个结构中,我有一个指向另一个结构类型的对象的指针成员。为了提高可读性并明确指出前向声明适用于需要它的结构,我将前向声明放在内部结构本身中。像这样

class Enclosing{
public:
    struct InnerA{
       struct InnerB; // forward declaration inside InnerA to improve readability  
       InnerB* b; 
       // other members
   };

    struct InnerB{

       // lots of member variables
    };
};

然后我在外面的某个地方有一个函数

void DoSomething(){
    Enclosing::InnerA a;


    // error incompatible types Enclosing::InnerB* and Enclosing::InnerA::InnerB*
    Enclosing::InnerB* ptr = a.b; 
}

据我了解,前向声明仅是一种告诉编译器类的方法,而不是定义完全不同的新类型。这是标准吗?如果是这样,是否有一种方法可以在结构内部包含前向声明而不会被视为其他类型?

2 个答案:

答案 0 :(得分:7)

是的,它被认为是另一种类型。

声明将名称放入声明出现的范围。每个类都介绍自己的范围。因此,在您的情况下,您拥有Enclosing::InnerA::InnerB,与Enclosing::InnerB显然不同。

恐怕没有办法在当前范围之外的其他范围内声明名称。您只需在使用InnerB的定义之前直接在Enclosing内部声明InnerA

答案 1 :(得分:4)

您的前向声明嵌套了两次,您正在前向声明SELECT cd.id, cd.customer_id, cd.customer_name, cp.phone_number, cp.updated FROM customer_data cd LEFT JOIN customer_phones cp ON cp.user_id=cd.customer_id AND cp.is_default_phone='1' AND cp.deleted IS NULL AND cp.updated = ( select max(updated) from customer_phones where user_id=cd.customer_id AND is_default_phone='1' AND deleted IS NULL ) ORDER BY cd.id ,但是您的定义是针对Enclosing::InnerA::InnerB的,因此您实际上正在前向声明其他类型。

您应该保持在同一级别:

Enclosing::InnerB

问题不是本质上的前向声明,就像您正在做的事情一样:

class Enclosing {
  struct InnerB;

  struct InnerA {
    InnerB* ptr;
  };
};

您会看到class Enclosing { struct InnerA { struct InnerB { int data; }; InnerB* ptr; }; struct InnerB { float data; }; }; Enclosing::InnerA::InnerB确实是不同的类型,这是因为声明像普通声明一样保留了其局部性。

相关问题