C++ 转发类声明是否可以在使用位置与class关键字互换?
这两个相等吗 代码1:C++ 转发类声明是否可以在使用位置与class关键字互换?,c++,C++,这两个相等吗 代码1: class B; class A { public: B fun1() const; B* m_b; }; extern void myfun( const B& b ); 代码2: class A { public: class B fun1() const; class B* m_b; }; extern void myfun( const class B& b ); 或者代码2中的使用编程风格是否存在一些问题
class B;
class A {
public:
B fun1() const;
B* m_b;
};
extern void myfun( const B& b );
代码2:
class A {
public:
class B fun1() const;
class B* m_b;
};
extern void myfun( const class B& b );
或者代码2中的使用编程风格是否存在一些问题?如果您有一个封闭的范围,这些问题就不同了 案例1:
class B { };
namespace test {
class B; // declares test::B
class A {
public:
B fun1() const; // refers to test::B
B* m_b; // also refers to test::B
};
class B { int x; }; // defines test::B
}
案例2:
class B { };
namespace test {
class A {
public:
class B fun1() const; // refers to ::B
class B* m_b; // also refers to ::B
};
class B { int x; }; // defines test::B
}
更多详情:
B类代码>是两件事之一。它要么是重新声明,要么是将名称B
引入当前范围的转发声明(§9.1[类名称]/p2)
类B
本身被称为一个精心设计的类型说明符。当您使用它声明某些内容时,编译器首先查找名为B
的类型是否在范围内(§3.4.4[basic.lookup.elab]/p2,§9.1[class.name]/p3注释)。如果有,则使用详细的类型说明符来引用该说明符
如果没有,那么它还将声明一个新名称。转发声明的区别在于声明此新名称的范围。如果用于指定命名空间作用域函数的返回类型或参数类型,则需要在包含声明的命名空间中声明名称;否则,除了作为友元声明外,该名称将在包含该声明的最小命名空间或块作用域中声明(§3.3.2[basic.scope.pdecl]/p7)。注意,这永远不会在类范围中声明名称;换句话说,它永远不会声明嵌套类
为什么使用前向声明而不是替代声明?首先,它可以在任何范围内声明名称,而不仅仅是块和命名空间范围。其次,前瞻性声明不那么脆弱。注意,在第二种情况下,如果我将test::B
的定义移动到test::A
之前,那么test::A
中的class B
s突然指代test::B
,而不是::B
。第三,您真的想记住一整段关于声明名称放入哪个范围的规则吗